SQL行转列查询求助
数据集结构与示例数据
表结构
| 字段 | 说明 |
|---|
| ID | 详情ID |
| Name | 详情类型(如sex、age) |
| 字段 | 说明 |
|---|
| CustomerID | 关联客户ID |
| DetailID | 关联详情ID |
| Values | 详情对应的值 |
示例数据
| CustomerID | DetailID | Values |
|---|
| 1 | 1 | M |
| 1 | 2 | 30 |
| 2 | 1 | F |
| 2 | 2 | 28 |
期望查询结果
尝试的SQL语句
select Customers.Name, Details.Name, DataValues.Value from Customers
inner join DataValues on DataValues.CustomersID = Customers.ID
inner join Details on DataValues.DetailsID = Details.ID
解决方案
你的原SQL返回的是每行对应一个客户的单个属性值,要将属性转成列展示,需要用条件聚合(适配多数数据库)或数据库原生的PIVOT功能,以下是具体实现:
通用条件聚合写法
SELECT
c.Name,
MAX(CASE WHEN d.Name = 'sex' THEN dv.Values END) AS Sex,
MAX(CASE WHEN d.Name = 'age' THEN dv.Values END) AS Age
FROM Customer c
JOIN DataValues dv ON c.ID = dv.CustomerID
JOIN Detail d ON dv.DetailID = d.ID
GROUP BY c.ID, c.Name;
- 用
CASE语句匹配详情类型,提取对应属性值 - 用
MAX聚合(因每个客户每个属性仅一个值,MIN也可),将同一客户的多行数据合并为一行 - 按客户ID和姓名分组,保证每个客户仅返回一行
支持PIVOT的数据库写法(如SQL Server)
SELECT Name, sex AS Sex, age AS Age
FROM (
SELECT c.Name, d.Name AS DetailName, dv.Values
FROM Customer c
JOIN DataValues dv ON c.ID = dv.CustomerID
JOIN Detail d ON dv.DetailID = d.ID
) AS SourceTable
PIVOT (
MAX(Values)
FOR DetailName IN (sex, age)
) AS PivotTable;
内容的提问来源于stack exchange,提问作者mehmet baki