我的原始表是这样的; 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
原始(来源)表格中的任何行都没有重复。
感谢。我尝试使用循环,但无法使其工作。三天以来一直坚持下去。
答案 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