我的表有一个ID int(PK),然后是col1-col32字符串。我的列中的值与时间不同。有时10有时会被填满等等。我可以使这个SQL动态,所以我不必用我所有的32列填充它吗?
WITH CTE
AS
(
SELECT *
FROM
(
SELECT ID,
Column_Name,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY col) row_num,
val
FROM tPivot A
INNER JOIN (SELECT Column_Name AS COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tPivot' ) B
ON A.ID = B.ORDINAL_POSITION - 1
UNPIVOT
(
val for col in (col1,col2,col3,col4,col5)
) unpvt
) A
PIVOT
(
MAX(val) FOR column_name IN (col1,col2,col3,col4,col5)
) pvt
)
SELECT *
FROM
(
SELECT ID,
row_num,
coalesce(col1,col2,col3,col4,col5) val
FROM cte
) A
PIVOT
(
MAX(val) FOR ID IN ([1],[2],[3],[4],[5])
) pvt
答案 0 :(得分:0)
大。
用于构建查询PIVOT
部分的ID(我的意思是([1],[2],[3],[4],[5])
)使用:
DECLARE @IDP AS NVARCHAR(MAX)
SELECT @IDP = STUFF((SELECT ',' + QUOTENAME(ID)
from (select distinct row_num as ID from CTE) q
group by q.ID
order by q.ID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
现在您可以在dynamic sql
中使用它:
DECLARE @sql AS NVARCHAR(MAX)
SET @sql='
WITH CTE
AS
(
SELECT *
FROM
(
SELECT ID,
Column_Name,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY col) row_num,
val
FROM tPivot A
INNER JOIN (SELECT Column_Name AS COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''tPivot'' ) B
ON A.ID = B.ORDINAL_POSITION - 1
UNPIVOT
(
val for col in (col1,col2,col3,col4,col5)
) unpvt
) A
PIVOT
(
MAX(val) FOR column_name IN (col1,col2,col3,col4,col5)
) pvt
)
SELECT *
FROM
(
SELECT ID,
row_num,
coalesce(col1,col2,col3,col4,col5) val
FROM cte
) A
PIVOT
(
MAX(val) FOR ID IN ('+@IDP+')
) pvt'
EXEC(@sql)
SQLFIDDLE DEMO基于您在评论中提到的小提琴演示中的架构和查询。
注意:也许您的原始查询可能会更加优化,我只是想说明如何使用动态sql来处理所有ID(行)