如何在SQL中以特定方式合并列

时间:2015-03-24 07:17:22

标签: sql sql-server

我的原始表是这样的; TableName = NewRetail

CustomerID  1    2   3      4    5     6      7.....30
    1       30  31   Null  Null Null   Null   Null
    2       24  78    35   72   Null   Null   Null

我想将此表存储在' Retail'

CustomerId Itemset 1 30 1 31 2 24 2 78 2 35 2 72

原始(来源)表格中的任何行都没有重复。

感谢。我尝试使用循环,但无法使其工作。三天以来一直坚持下去。

3 个答案:

答案 0 :(得分:2)

您可以table valued constructor使用Cross apply unpivot数据

SELECT CustomerID,
       Itemset
FROM   Yourtable
       CROSS apply (VALUES ([1]),([2]),([3]),([4]),([5]),([6]),([7]),...) cs (Itemset)
WHERE  Itemset IS NOT NULL 

动态版

DECLARE @itemset VARCHAR(max)='',
        @sql     NVARCHAR(max);

WITH cte
     AS (SELECT TOP 30 Row_number()OVER(ORDER BY (SELECT NULL)) RN
         FROM   sys.columns)
SELECT @itemset += '(' + Quotename(RN) + '),'
FROM   cte

SET @itemset = LEFT(@itemset, Len(@itemset) - 1)
SET @sql = 'SELECT CustomerID,
           Itemset
    FROM   Yourtable
           CROSS apply (VALUES ' + @itemset
           + ') cs (Itemset)
    WHERE  Itemset IS NOT NULL '

EXEC Sp_executesql @sql 

答案 1 :(得分:1)

您可以使用UNION ALL

执行此操作
SELECT *
FROM (
    SELECT CustomerId, [1] AS ItemSet FROM NewRetail UNION ALL
    SELECT CustomerId, [2] FROM NewRetail UNION ALL
    SELECT CustomerId, [3] FROM NewRetail UNION ALL
    SELECT CustomerId, [4] FROM NewRetail UNION ALL
    SELECT CustomerId, [5] FROM NewRetail UNION ALL
    SELECT CustomerId, [6] FROM NewRetail UNION ALL
    SELECT CustomerId, [7] FROM NewRetail UNION ALL
    ...
    SELECT CustomerId, [30] FROM NewRetail
)t
WHERE ItemSet IS NOT NULL
ORDER BY CustomerId

使用动态SQL:

;WITH Tally(N) AS(
    SELECT TOP 30 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM sys.columns
)
SELECT @sql = @sql +  
    CASE 
        WHEN @sql = '' THEN 'SELECT CustomerId, [' + CONVERT(VARCHAR(2), N) + '] AS ItemSet FROM NewRetail' 
        ELSE ' UNION ALL' + CHAR(10) +' SELECT CustomerId, [' + CONVERT(VARCHAR(2), N) + '] FROM NewRetail'
    END
    FROM Tally

SELECT @sql = 
'SELECT *
FROM (
    ' + @sql + CHAR(10) +
')t
WHERE ItemSet IS NOT NULL
ORDER BY CustomerId'

PRINT @sql
EXEC (@sql)

答案 2 :(得分:1)

这是一个简单的UNPIVOT操作。从结果中自动消除NULL:

declare @t table(custid int, [1] int, [2] int, [3] int)

insert into @t values
(1, 10, 30, null),
(2, 30, 40, 50)


select custid, c from @t
unpivot(c for p in([1], [2], [3])) p

小提琴http://sqlfiddle.com/#!6/9eecb/1733