SQL查询supplier与contacts主从表实现格式化结果返回方法
关联表结构说明
- 主表
supplier:供应商主表,主键为ID,核心字段Name存储供应商名称 - 从表
contacts:联系人从表,通过supplierId字段关联supplier.ID,Contact字段存储联系人姓名
第一种:聚合拼接模式输出
核心逻辑是按供应商分组后,用数据库内置的字符串聚合函数,把同组下的联系人按顺序拼接成逗号分隔的单字段。
以最常用的MySQL为例,查询语句如下:
SELECT s.ID, s.Name, GROUP_CONCAT(c.Contact ORDER BY c.id SEPARATOR ', ') AS Contact FROM supplier s LEFT JOIN contacts c ON s.ID = c.supplierId GROUP BY s.ID, s.Name;
查询返回结果:
| ID | Name | Contact |
|---|---|---|
| 1 | Hp | John, Smith, Will |
| 2 | Huawei | Doe, Wick |
其他数据库适配说明:
- Oracle:将
GROUP_CONCAT(...)段替换为LISTAGG(c.Contact, ', ') WITHIN GROUP (ORDER BY c.id)- PostgreSQL / SQL Server:将
GROUP_CONCAT(...)段替换为STRING_AGG(c.Contact, ', ' ORDER BY c.id)
第二种:行转列模式输出
核心逻辑是先给每个供应商下的联系人按录入顺序编排序号,再通过条件聚合把不同序号的联系人映射到独立列,无对应值的位置自动留空。
该写法兼容所有支持窗口函数的数据库(MySQL8.0+、PostgreSQL、Oracle、SQL Server等),语句如下:
WITH contact_sorted AS ( SELECT supplierId, Contact, ROW_NUMBER() OVER (PARTITION BY supplierId ORDER BY id) AS contact_sort FROM contacts ) SELECT s.ID, s.Name, MAX(CASE WHEN cs.contact_sort = 1 THEN cs.Contact END) AS Contact1, MAX(CASE WHEN cs.contact_sort = 2 THEN cs.Contact END) AS Contact2, MAX(CASE WHEN cs.contact_sort = 3 THEN cs.Contact END) AS Contact3 FROM supplier s LEFT JOIN contact_sorted cs ON s.ID = cs.supplierId GROUP BY s.ID, s.Name;
查询返回结果:
| ID | Name | Contact1 | Contact2 | Contact3 |
|---|---|---|---|---|
| 1 | Hp | John | Smith | Will |
| 2 | Huawei | Doe | Wick | 空值 |
注意:如果后续单个供应商下的联系人数量超过3个,只需要对应增加序号匹配的
MAX(CASE...)段即可扩展列数。
内容的提问来源于stack exchange,提问作者Tufail Ahmed
相关产品推荐
相关产品推荐

