SQL:通过某些ID合并两行并保留值

时间:2019-07-15 17:49:30

标签: php mysql sql laravel

我面临一个相对简单的问题,但是我无法设法解决问题。请记住,我正在将PHP与Laravel框架一起使用,如果它可以使事情变得更容易。

我有一张桌子,上面满是这样的数据:

ID | TRANSACTION_ID | BEACON_TYPE
---+----------------+---------------
 1 |       1        |  "abc"
 2 |       2        |  "def"
 3 |       2        |  "xyz"

,我想按交易ID对它们进行分组,并将信标类型保留在数据中,如下所示:

ID | TRANSACTION_ID | BEACON_TYPE
---+----------------+---------------
 1 |       1        |  "abc"
 2 |       2        |  "def", "xyz"

我尝试使用group by无济于事。关于如何实现这一目标的任何想法或提示?就像我之前说的,Laravel Eloquent可能有某种方法。

3 个答案:

答案 0 :(得分:3)

假设您正在使用MySQL,则要查找的功能是GROUP_CONCAT()。使用口才,看起来像这样:

$transactions = DB::table('tableName')
                  ->select('TRANSACTION_ID', DB::raw('GROUP_CONCAT(BEACON_TYPE SEPARATOR ', ') as BEACON_TYPE'))
                  ->groupBy('TRANSACTION_ID')
                  ->get();

请注意,如果要更改分隔符,只需将', '编辑为其他内容。默认分隔符为','

答案 1 :(得分:3)

使用GROUP_CONCAT()连接组的值。给它一个SEPARATOR中的一个', ',以得到用逗号分隔值的组。

您的预期结果将丢失一些信息,因为分组行的ID分别为2和3(在您的示例中)。因此,要么不选择这些ID,要么不添加一个单独的GROUP_CONCAT()

原始SQL查询将使用GROUP_CONCAT()。以下查询使用表foo,将其替换为您的实际表名。

SELECT TRANSACTION_ID, 
       GROUP_CONCAT(BEACON_TYPE SEPARATOR ', ') AS BEACON_TYPE
FROM foo
GROUP BY TRANSACTION_ID

使用Eloquent,您需要使用DB::raw()来选择GROUP_CONCAT()部分,因为GROUP_CONCAT()没有Eloquent方法,所以它变成了

$result = DB::table('foo')
            ->select('TRANSACTION_ID',
                      DB::raw("GROUP_CONCAT(BEACON_TYPE SEPARATOR ', '") as BEACON_TYPE)
            ->groupBy('TRANSACTION_ID');

或者如果要将分组的ID包含到其中,那么..

$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');

答案 2 :(得分:1)

如果您已经有数据库中的数据,并且只想使用collection functions,则可以执行以下操作:

    $things = $things->groupBy('TRANSACTION_ID')
            ->map(function($x) {
                $beaconTypes = $x->implode('BEACON_TYPE', ', ');
                $firstThing = $x->first();
                $firstThing['BEACON_TYPE'] = $beaconTypes;

                return $firstThing;
            });