能否编写SELECT语句将1:N关联的CAR与Holder_Data表数据单行展示?
当然可以搞定!你要的就是把同一车辆对应的多个车主信息合并到一行里,这在SQL里是很常见的需求,不同数据库有专门的字符串聚合函数来实现,我给你分几种主流数据库的写法举例:
MySQL/MariaDB 实现方式
用GROUP_CONCAT函数就能轻松把同一车牌下的车主信息合并成一个字符串,还能自定义分隔符:
SELECT c.License_Plate_PK, c.Frame, c.Car_Info, GROUP_CONCAT(h.Holder_Data SEPARATOR ', ') AS All_Holders FROM Car c LEFT JOIN Holder_Data h ON c.License_Plate_PK = h.License_Plate_FK GROUP BY c.License_Plate_PK, c.Frame, c.Car_Info;
- 用
LEFT JOIN是为了确保即使没有对应车主的车辆也能被查询出来; - 如果需要去重(比如同一车主重复记录),可以改成
GROUP_CONCAT(DISTINCT h.Holder_Data SEPARATOR ', '); - 默认分隔符是逗号,你可以换成任何你需要的符号,比如换行符
'\n'。
SQL Server 实现方式
SQL Server 2017及以上版本支持STRING_AGG函数,用法更直观:
SELECT c.License_Plate_PK, c.Frame, c.Car_Info, STRING_AGG(h.Holder_Data, ', ') AS All_Holders FROM Car c LEFT JOIN Holder_Data h ON c.License_Plate_PK = h.License_Plate_FK GROUP BY c.License_Plate_PK, c.Frame, c.Car_Info;
同样支持去重:STRING_AGG(DISTINCT h.Holder_Data, ', '),如果需要排序还可以加WITHIN GROUP (ORDER BY h.Holder_Data)。
PostgreSQL 实现方式
PostgreSQL同样用STRING_AGG函数,语法和SQL Server类似:
SELECT c.License_Plate_PK, c.Frame, c.Car_Info, STRING_AGG(h.Holder_Data, ', ') AS All_Holders FROM Car c LEFT JOIN Holder_Data h ON c.License_Plate_PK = h.License_Plate_FK GROUP BY c.License_Plate_PK, c.Frame, c.Car_Info;
如果要按特定顺序合并车主信息,加上排序即可:STRING_AGG(h.Holder_Data, ', ') ORDER BY h.Holder_Data。
Oracle 实现方式
Oracle用LISTAGG函数,需要指定排序规则:
SELECT c.License_Plate_PK, c.Frame, c.Car_Info, LISTAGG(h.Holder_Data, ', ') WITHIN GROUP (ORDER BY h.Holder_Data) AS All_Holders FROM Car c LEFT JOIN Holder_Data h ON c.License_Plate_PK = h.License_Plate_FK GROUP BY c.License_Plate_PK, c.Frame, c.Car_Info;
如果要处理大量数据避免字符长度限制,可以用LISTAGG(... ON OVERFLOW TRUNCATE)来截断超长内容。
核心思路总结
本质上就是按车辆的唯一标识(车牌)分组,然后用数据库提供的字符串聚合函数,把同一分组下的所有Holder_Data字段值合并成单个字符串,这样就能实现同一车辆的所有信息和车主数据在同一行展示了。
内容的提问来源于stack exchange,提问作者Simo
相关产品推荐
相关产品推荐

