【问题标题】:SQL : Merge two rows by some ID and keep valuesSQL:通过某个 ID 合并两行并保留值
【发布时间】:2019-07-15 17:49:30
【问题描述】:

我面临着一个相对简单的问题,但我无法想出一个解决方案。请记住,我将 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 可能有一些方法可以做到这一点。

【问题讨论】:

  • 您说您期望的结果将无效 - ID 可以是 2 或 3,因此您“丢失”了信息。删除 ID,或将其添加到 GROUP_CONCAT()

标签: php mysql sql laravel


【解决方案1】:

假设您使用的是 MySQL,您要查找的函数是 GROUP_CONCAT()。使用 Eloquent,它看起来像这样:

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

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

【讨论】:

  • 我知道存在 GROUP_CONCAT() 之类的东西,但找不到要查找的正确措辞。感谢 Stackoverflow 社区,您永远不会失望 ;)
【解决方案2】:

使用GROUP_CONCAT() 连接组的值。给它一个SEPARATOR', ' 以获取具有逗号分隔值的组。

您的预期结果会丢失一些信息,因为分组行的IDs 将是 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');

【讨论】:

  • 简洁的答案。感谢您花时间在这上面。我会检查一下并及时通知您。
【解决方案3】:

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

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

                return $firstThing;
            });

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2021-12-23
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多