SQL - 按一列分组,但从不同的行中选择多列作为列

时间:2015-01-28 08:15:48

标签: sql tsql group-by pivot

我的桌子看起来像这样:

+----+------+--------+--------+--------+-------+
| 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  |
+----+------+--------+--------+--------+-------+

选择之后我想得到的结果如下:

+------+---------+---------+---------+---------+---------------+
| 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 notes的值。标题名称并不重要,只需要将所需的数据字段输入结果。

由于

解决方案: 得到它的工作结束查询 - >

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

现在还有一个问题 - &gt;为什么我必须将typeids转换为字符串值? (原来在数据库中它们是日期时间,但是当我不转换时它会引发错误)@NoDisplayName

1 个答案:

答案 0 :(得分:1)

由于您要转动两列valuenotes,我建议您先使用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