将所有值展开到一列中

时间:2016-08-03 15:26:59

标签: sql-server tsql

我有一张很宽的桌子。我想要做的就是将行的每个值放入一个列中。我也不能硬编码列名称,因为我在许多不同的表上执行此操作。所以,它必须是动态的。最后,请假设表格中只有一行。

是否有一种简单的方法来解决表格中的每个值?

当前

Col_A   Col_B   Col_C   Col_D
  a        b      c       d

期望的结果

Col_Index   Col_Value
    1           a
    2           b
    3           c
    4           d

传统的unpivot示例没有用,因为我需要一种简单,动态的方式来解开每一行/列。 Unpivot适用于一个或几个,而不是全部。

3 个答案:

答案 0 :(得分:1)

这应该将序数位置作为Col_Index并将转换后的字段动态地作为Col_Value

DECLARE @sql NVARCHAR(MAX),
        @columns NVARCHAR(Max),
        @ordinals NVARCHAR(Max),
        @table VARCHAR(200) = 'table'



SELECT @columns = STUFF ((SELECT    ',CAST(' + QUOTENAME(column_name) + ' AS VARCHAR(MAX)) AS ' + QUOTENAME(ORDINAL_POSITION)
                          FROM      information_schema.columns 
                          WHERE     table_name=@table
                          ORDER BY ORDINAL_POSITION FOR XML PATH('')), 1, 1, ''),
        @ordinals = STUFF ((SELECT  ',' + QUOTENAME(ORDINAL_POSITION)
                          FROM      information_schema.columns 
                          WHERE     table_name=@table
                          ORDER BY ORDINAL_POSITION FOR XML PATH('')), 1, 1, '')

SET @sql = N'
    SELECT  Col_Index,
            Col_Value
    FROM    ( SELECT ' +  @columns + ' FROM ' + @table + ') t
    UNPIVOT (
        Col_Value
        FOR Col_Index in (' + @ordinals + ')
    ) up
'

如果您有多个模式,则需要将其与表名一起定义,并将其添加到选择查询中的表名

答案 1 :(得分:0)

select a1.*,ROW_NUMBER() over (order by (select null)) as col_index from #t t
cross apply
(
values(col_a),
      (col_b),
      (col_c),
      (col_d)
)a1(val)

答案 2 :(得分:0)

CREATE Table
ColTable
(
    Col_A VARCHAR(256),
    Col_B VARCHAR(256),
    Col_C VARCHAR(256),
    Col_D VARCHAR(256),
)

INSERT INTO ColTable (Col_A,Col_B,Col_C,Col_D)
Values ('a','b','c','d')

SELECT * FROM ColTable


SELECT
    Ordinal AS Col_Index
    ,ColInfo AS Col_Value
FROM
(
    SELECT 
        Col_A
        ,Col_B
        ,Col_C
        ,Col_D
        ,1 AS [OrdinalA]
        ,2 AS [OrdinalB]
        ,3 AS [OrdinalC]
        ,4 AS [OrdinalD]
    FROM 
        ColTable
    ) AS d
    UNPIVOT
    (
        ColInfo FOR ColInfos IN (Col_A, Col_B, Col_C, Col_D)
    ) AS l
    UNPIVOT
    (
        Ordinal FOR Ordinals IN (OrdinalA, OrdinalB, OrdinalC, OrdinalD)
    ) AS o
WHERE
    RIGHT(ColInfos,1) = RIGHT(Ordinals,1)


DROP TABLE ColTable