简体   繁体   English

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

[英]SQL : Merge two rows by some ID and keep values

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. 请记住,我正在将PHP与Laravel框架一起使用,如果它可以使事情变得更容易的话。

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对它们进行分组,并在数据中保留信标类型,如下所示:

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. 就像我之前说的,Laravel Eloquent可能有一些方法可以做到这一点。

Assuming you're using MySQL, the function you're looking for is GROUP_CONCAT() . 假设您正在使用MySQL, GROUP_CONCAT()查找的功能是GROUP_CONCAT() Using Eloquent, it would look something like this: 使用Eloquent,它看起来像这样:

$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. 使用GROUP_CONCAT()连接组的值。 Give it a SEPARATOR of ', ' to get the groups with comma separated values. 给它一个SEPARATOR ', '来得到带有逗号分隔值的组。

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). 您期望的结果将丢失一些信息,因为分组行的ID均为2和3(在您的示例中)。 So either don't select those IDs, or add them with a separate GROUP_CONCAT() . 因此,要么不选择这些ID,要么不使用单独的GROUP_CONCAT()添加它们。

The raw SQL query would be using GROUP_CONCAT() . 原始SQL查询将使用GROUP_CONCAT() The following queries use the table foo , replace that with your actual table name. 以下查询使用表foo ,将其替换为您的实际表名。

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 使用口若悬河,你需要使用DB::raw()选择GROUP_CONCAT()的一部分,因为是为没有雄辩的方法GROUP_CONCAT()所以后来就变成

$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.. 或者,如果您想将分组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');

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;
            });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM