SQL 将多行转置到不同的列
Posted
技术标签:
【中文标题】SQL 将多行转置到不同的列【英文标题】:SQL transpose multiple rows to different columns 【发布时间】:2021-10-15 11:43:03 【问题描述】:我有 SQL server 数据表,像这样:
ID | SYMPTOM1 | SYMPTOM2 |
---|---|---|
1 | A | B |
1 | C | D |
2 | E | F |
3 | A | C |
3 | D | E |
我想得到这个:
ID | SYMPTOM1 | SYMPTOM2 | SYMPTOM3 | SYMPTOM4 |
---|---|---|---|---|
1 | A | B | C | D |
2 | E | F | ||
3 | A | C | D | E |
这应该是一个“简单”的支点,但我想不通。 如何编写 SQL 查询?
*编辑
对不起,我忽略了一个重要的细节。表中的行数非常大,大约 500.000,因此 ID 非常大。
【问题讨论】:
您希望它作为一个使用 tsql-PIVOT 的枢轴还是一个条件聚合? (即 sqlserver 特定解决方案或 SQL 通用解决方案)。症状表达的顺序重要吗? 这能回答你的问题吗? Group by column and multiple Rows into One Row multiple columns 【参考方案1】:您可以将其作为自连接进行 - 使用行号来获得另一列 1 或 2(取决于 ID 出现的次数),1 应该始终出现,2 有时出现,所以左加入这些行2 到那些有 1 的行(基于 id)给你最终结果..
WITH x AS(
SELECT
t.ID,
t.SYMPTOM1,
t.SYMPTOM2,
ROW_NUMBER() OVER (PARTITION BY t.ID ORDER BY t.SYMPTOM1) as rn
FROM t
)
SELECT
*
FROM
x x1
LEFT JOIN x x2 ON x1.id = x2.id AND x1.rn = 1 AND x2.rn = 2
【讨论】:
听起来效率低下 衡量,不要猜测 @spiderman 错字,谢谢指出【参考方案2】:您可以以行号为轴
SELECT
t.ID,
SYMPTOM1 = MAX(CASE WHEN t.rn = 1 THEN t.SYMPTOM1 END),
SYMPTOM2 = MAX(CASE WHEN t.rn = 1 THEN t.SYMPTOM2 END),
SYMPTOM3 = MAX(CASE WHEN t.rn = 2 THEN t.SYMPTOM1 END),
SYMPTOM4 = MAX(CASE WHEN t.rn = 2 THEN t.SYMPTOM2 END)
FROM (
SELECT
t.*,
rn = ROW_NUMBER() OVER (PARTITION BY t.ID ORDER BY (SELECT 1))
FROM YourTable t
) t
GROUP BY t.ID;
【讨论】:
这里实际上不需要反透视。只需对RN
的每个值进行 2 个条件聚合; 1 个用于Symptom1
,另一个用于Symptom2
。
非常正确,谢谢以上是关于SQL 将多行转置到不同的列的主要内容,如果未能解决你的问题,请参考以下文章