如何在MySQLi中使用Group By并保留所有列的关联值?
如何用GROUP BY同时保留列中所有关联值?
你肯定遇到过这种场景:想按某一列(比如这里的month)做分组,同时把每个分组里关联的其他列值都整合在一起展示,就像你给出的需求一样。
现有数据表
| month | date | location |
|---|---|---|
| april | 4/11/18 | US |
| april | 4/16/18 | US |
| may | 5/14/18 | Canada |
| june | 6/05/18 | Canada |
| june | 6/30/18 | US |
期望输出
april: 4/11/18 (US), 4/16/18 (US) may: 5/14/18 (Canada) june: 6/05/18 (Canada), 6/30/18 (US)
不同数据库的实现方案
不同数据库有各自专门的字符串聚合函数,下面是几种常用数据库的写法:
1. MySQL/MariaDB
用GROUP_CONCAT()就能轻松实现,先把date和location拼接成目标格式,再聚合分组:
SELECT month, GROUP_CONCAT(CONCAT(date, ' (', location, ')') SEPARATOR ', ') AS details FROM your_table_name GROUP BY month;
2. PostgreSQL
PostgreSQL用STRING_AGG()函数,用法和MySQL的GROUP_CONCAT()很像:
SELECT month, STRING_AGG(CONCAT(date, ' (', location, ')'), ', ') AS details FROM your_table_name GROUP BY month;
3. SQL Server
- SQL Server 2017及以后版本:支持
STRING_AGG(),写法简洁:
SELECT month, STRING_AGG(CONCAT(date, ' (', location, ')'), ', ') AS details FROM your_table_name GROUP BY month;
- 更早版本:需要用
FOR XML PATH来拼接字符串,再用STUFF去掉开头多余的分隔符:
SELECT DISTINCT month, STUFF( (SELECT ', ' + CONCAT(date, ' (', location, ')') FROM your_table_name t2 WHERE t2.month = t1.month FOR XML PATH('')), 1, 2, '' ) AS details FROM your_table_name t1;
4. Oracle
Oracle用LISTAGG()函数,还能指定排序保证日期顺序:
SELECT month, LISTAGG(CONCAT(date, ' (', location, ')'), ', ') WITHIN GROUP (ORDER BY date) AS details FROM your_table_name GROUP BY month;
内容的提问来源于stack exchange,提问作者pdas
相关产品推荐
相关产品推荐

