使我的SQL查询动态化

时间:2015-04-07 11:13:27

标签: sql sql-server dynamic

我的表有一个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

1 个答案:

答案 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(行)