SQL - 按一列分组,但 select 来自不同行的多列作为列
SQL - group by one column but select multiple columns from different rows as colums
我有 table 看起来像这样:
+----+------+--------+--------+--------+-------+
| ID | AcID | TypeID | Value1 | Value2 | Notes |
+----+------+--------+--------+--------+-------+
| 1 | 33 | 1 | Hash1 | Dash1 | |
| 2 | 33 | 2 | Hash2 | Dash2 | |
| 3 | 33 | 3 | Hash3 | Dash3 | |
| 4 | 33 | 4 | Hash4 | Dash4 | lala |
+----+------+--------+--------+--------+-------+
在 select 之后,我希望得到如下所示的结果:
+------+---------+---------+---------+---------+---------------+
| AcID | TypeID1 | TypeID2 | TypeID3 | TypeID4 | TypeID4_Notes |
+------+---------+---------+---------+---------+---------------+
| 33 | Hash1 | Hash2 | Hash3 | Dash4 | lala |
+------+---------+---------+---------+---------+---------------+
使用 Pivot 我可以获得:
SELECT [1], [2], [3], [4]
FROM SourceTable
PIVOT
(
MAX(value1)
FOR typeID IN ( [1], [2], [3], [4])
) AS PivotTable
结果:
+-------+-------+-------+-------+
| Type1 | Type2 | Type3 | Type4 |
+-------+-------+-------+-------+
| hash1 | Hash2 | Hash3 | Hash4 |
+-------+-------+-------+-------+
我如何将 actID 添加到结果 + 将 type4 值更改为 Dash4 并添加名为 Notes 的列,其中包含 type4 注释的值。 Header 名称无关紧要,只需要将所需的数据字段放入结果中即可。
谢谢
解决方法:
完成查询 ->
SELECT * FROM (SELECT AcID,
CASE
WHEN cname = 'Notes' THEN 'typeID' + CONVERT(VARCHAR(15), typeID) + '_' + cname
ELSE cname + CONVERT(VARCHAR(15), typeID)
END AS typeid,
data
FROM (SELECT id,
AcID,
typeID,
CASE
WHEN typeID <> 4 THEN Value1
ELSE Value2
END AS typeids,
Notes
FROM mytable) a
CROSS apply (VALUES ('typeid',CONVERT(VARCHAR(150),typeids)),
('Notes',notes)) cs(cname, data)) b
PIVOT (Max(data)
FOR typeid IN ([typeid1],[typeid2],[typeid3],[typeid4],
[typeid4_Notes] )) pv
现在还有一个问题 -> 为什么我必须将 typeids 转换为字符串值? (最初在数据库中它们是日期时间,但是当我不转换时它会抛出错误)@NoDisplayName
因为你想旋转两列 value
和 notes
我建议你首先使用 cross apply
将两列转换为单列
然后旋转该列以获得结果。
SELECT *
FROM (SELECT AcID,
CASE
WHEN cname = 'notes' THEN 'typeid' + CONVERT(VARCHAR(15), id) + '_' + cname
ELSE cname + CONVERT(VARCHAR(15), id)
END AS typeid,
data
FROM (SELECT id,
AcID,
CASE
WHEN notes <> '' THEN Value1
ELSE Value2
END AS typeids,
Notes
FROM Yourtable) a
CROSS apply (VALUES ('typeid',typeids),
('Notes',notes)) cs(cname, data)) b
PIVOT (Max(data)
FOR typeid IN ([typeid1],[typeid2],[typeid3],[typeid4],
[typeid4_Notes] )) pv
我有 table 看起来像这样:
+----+------+--------+--------+--------+-------+
| ID | AcID | TypeID | Value1 | Value2 | Notes |
+----+------+--------+--------+--------+-------+
| 1 | 33 | 1 | Hash1 | Dash1 | |
| 2 | 33 | 2 | Hash2 | Dash2 | |
| 3 | 33 | 3 | Hash3 | Dash3 | |
| 4 | 33 | 4 | Hash4 | Dash4 | lala |
+----+------+--------+--------+--------+-------+
在 select 之后,我希望得到如下所示的结果:
+------+---------+---------+---------+---------+---------------+
| AcID | TypeID1 | TypeID2 | TypeID3 | TypeID4 | TypeID4_Notes |
+------+---------+---------+---------+---------+---------------+
| 33 | Hash1 | Hash2 | Hash3 | Dash4 | lala |
+------+---------+---------+---------+---------+---------------+
使用 Pivot 我可以获得:
SELECT [1], [2], [3], [4]
FROM SourceTable
PIVOT
(
MAX(value1)
FOR typeID IN ( [1], [2], [3], [4])
) AS PivotTable
结果:
+-------+-------+-------+-------+
| Type1 | Type2 | Type3 | Type4 |
+-------+-------+-------+-------+
| hash1 | Hash2 | Hash3 | Hash4 |
+-------+-------+-------+-------+
我如何将 actID 添加到结果 + 将 type4 值更改为 Dash4 并添加名为 Notes 的列,其中包含 type4 注释的值。 Header 名称无关紧要,只需要将所需的数据字段放入结果中即可。
谢谢
解决方法: 完成查询 ->
SELECT * FROM (SELECT AcID,
CASE
WHEN cname = 'Notes' THEN 'typeID' + CONVERT(VARCHAR(15), typeID) + '_' + cname
ELSE cname + CONVERT(VARCHAR(15), typeID)
END AS typeid,
data
FROM (SELECT id,
AcID,
typeID,
CASE
WHEN typeID <> 4 THEN Value1
ELSE Value2
END AS typeids,
Notes
FROM mytable) a
CROSS apply (VALUES ('typeid',CONVERT(VARCHAR(150),typeids)),
('Notes',notes)) cs(cname, data)) b
PIVOT (Max(data)
FOR typeid IN ([typeid1],[typeid2],[typeid3],[typeid4],
[typeid4_Notes] )) pv
现在还有一个问题 -> 为什么我必须将 typeids 转换为字符串值? (最初在数据库中它们是日期时间,但是当我不转换时它会抛出错误)@NoDisplayName
因为你想旋转两列 value
和 notes
我建议你首先使用 cross apply
然后旋转该列以获得结果。
SELECT *
FROM (SELECT AcID,
CASE
WHEN cname = 'notes' THEN 'typeid' + CONVERT(VARCHAR(15), id) + '_' + cname
ELSE cname + CONVERT(VARCHAR(15), id)
END AS typeid,
data
FROM (SELECT id,
AcID,
CASE
WHEN notes <> '' THEN Value1
ELSE Value2
END AS typeids,
Notes
FROM Yourtable) a
CROSS apply (VALUES ('typeid',typeids),
('Notes',notes)) cs(cname, data)) b
PIVOT (Max(data)
FOR typeid IN ([typeid1],[typeid2],[typeid3],[typeid4],
[typeid4_Notes] )) pv