SQL 根据另一列的值添加列

SQL Add columns based on value from another column

我有一个 table 这样的:

id cols val
1 date 01-01-01
1 name abc
1 flag True
1 end_date null
2 date 01-01-02
2 name abcd
2 flag False
2 end_date 01-01-03

我需要创建一个看起来像

的table
id date name flag end_date
1 01-01-01 abc True null
2 01-01-02 abcd False 01-01-03

我只能用select/with。无功能或 create/update

感谢您的帮助

您可以使用 PIVOT 和 UNPIVOT 关系运算符将 table-valued 表达式更改为另一个 table。 PIVOT 通过将表达式中一列的唯一值转换为输出中的多列来旋转 table-valued 表达式。

https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15

你可以使用这个查询 pivot it table value

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.cols) 
            FROM yourtablename c
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT Id, ' + @cols + ' from 
            (
                select id
                    ,val
                from yourtablename
           ) x
            pivot 
            (
                 val
                for cols in (' + @cols + ')
            ) p '


execute(@query);  

要记住的一个有趣技巧是,您可以对文本值使用 MAX(CASE WHEN... 以获得如下结果:

SELECT id
, MAX(CASE WHEN cols = 'date' THEN val ELSE NULL END) AS dt
, MAX(CASE WHEN cols = 'name' THEN val ELSE NULL END) AS nm
, MAX(CASE WHEN cols = 'flag' THEN val ELSE NULL END) AS flag
, MAX(CASE WHEN cols = 'end_date' THEN val ELSE NULL END) AS end_date
FROM #t
GROUP BY id

我尽量避免使用 SQL 关键字作为列名,因此您使用 dtnm 而不是 datename

您可能还想应用一些类型转换以使其成为更有用的格式。

dbfiddle.uk