I'm facing a relatively easy problem but I can't manage to wrap my head around a solution. Keep in mind I'm using PHP with the Laravel framework if it can makes things any easier.
I have a table filled with data like so :
ID | TRANSACTION_ID | BEACON_TYPE
---+----------------+---------------
1 | 1 | "abc"
2 | 2 | "def"
3 | 2 | "xyz"
and I would like to group them by transaction ID and to keep the beacon type inside the data like so:
ID | TRANSACTION_ID | BEACON_TYPE
---+----------------+---------------
1 | 1 | "abc"
2 | 2 | "def", "xyz"
I've tried using group by with no avail. Any ideas or hints on how to accomplish that? As I said earlier there might be some way to do it with Laravel Eloquent.
Assuming you're using MySQL, the function you're looking for is GROUP_CONCAT()
. Using Eloquent, it would look something like this:
$transactions = DB::table('tableName')
->select('TRANSACTION_ID', DB::raw('GROUP_CONCAT(BEACON_TYPE SEPARATOR ', ') as BEACON_TYPE'))
->groupBy('TRANSACTION_ID')
->get();
Note, if you want to change the separator, you just need to edit the ', '
to something else. The default separator is ','
.
Use GROUP_CONCAT()
to concatenate values of the group. Give it a SEPARATOR
of ', '
to get the groups with comma separated values.
Your expected result is going to lose some information, since the ID
s of the grouped row will be both 2 and 3 (in your example). So either don't select those IDs, or add them with a separate GROUP_CONCAT()
.
The raw SQL query would be using GROUP_CONCAT()
. The following queries use the table foo
, replace that with your actual table name.
SELECT TRANSACTION_ID,
GROUP_CONCAT(BEACON_TYPE SEPARATOR ', ') AS BEACON_TYPE
FROM foo
GROUP BY TRANSACTION_ID
Using Eloquent, you need to use DB::raw()
to select the GROUP_CONCAT()
part, as there's no Eloquent method for GROUP_CONCAT()
, so then it becomes
$result = DB::table('foo')
->select('TRANSACTION_ID',
DB::raw("GROUP_CONCAT(BEACON_TYPE SEPARATOR ', '") as BEACON_TYPE)
->groupBy('TRANSACTION_ID');
or if you want to include the grouped IDs to, then..
$result = DB::table('foo')
->select('TRANSACTION_ID',
DB::raw("GROUP_CONCAT(BEACON_TYPE SEPARATOR ', '") as BEACON_TYPE),
DB::raw("GROUP_CONCAT(ID SEPARATOR ', '") as ID)
->groupBy('TRANSACTION_ID');
If you already have the data from the database and just want to use collection functions you can do the following:
$things = $things->groupBy('TRANSACTION_ID')
->map(function($x) {
$beaconTypes = $x->implode('BEACON_TYPE', ', ');
$firstThing = $x->first();
$firstThing['BEACON_TYPE'] = $beaconTypes;
return $firstThing;
});