我可以使用不同数据类型的键值表创建动态数据透视查询吗?

时间:2015-02-11 20:07:52

标签: sql-server pivot key-value dynamic-sql

我有一个键值对表。我已经使用动态sql创建了一个脚本,可以正确地转动表格。但是,密钥具有不同的数据类型。有没有办法在枢轴动态期间或之后动态转换键?我可以在每个键的相同键值对表中或在可通过键链接的单独表中使用数据类型。

使用动态sql是因为我不会总是知道列。总会有数据类型。

起始表的一个例子:

sampleid     key   value    datatype
------------------------------------
1001        Name   Andrew    varchar(50)
1001        Date   20150129  datetime
1002        Name   Anna      varchar(50)
1002        Date   20150129  datetime

最终结果是名称为nvarchar,日期为datetime: 该脚本是一个存储过程,可将其创建到视图中。该视图通过SAS和Olive等外部应用程序访问,从视图中获取数据类型。当然这不是理想的,但这是我一直在尝试的任务!

sampleid  name      date
-----------------------------
1001     Andrew    20150129
1002     Anna      20150129

1 个答案:

答案 0 :(得分:3)

您可以使用动态SQL执行此操作,您只需要将两个单独的“新列”列表作为字符串创建。一个列表将包括要转换为您的数据类型的列名,第二个列将用于PIVOT函数。

代码如下:

DECLARE 
    @cols AS NVARCHAR(MAX),
    @colsConversion AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

-- get the list of [key] items for the columns used in the PIVOT
select @cols 
  = STUFF((SELECT ', ' + QUOTENAME([key])
            from yourtable
            group by [key], datatype           
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

-- get the list of columns for the final select
-- include a conversion of the columns into the correct datatype
select @colsConversion 
  = STUFF((SELECT ', cast(' + QUOTENAME([key]) +' as '+ datatype+') as ' + QUOTENAME([key])
            from yourtable
            group by [key], datatype           
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

-- the converted columns go in the final select list 
-- while the other @cols are used inside the PIVOT
set @query = 'SELECT sampleid, ' + @colsConversion + ' 
            from 
            (
              select sampleid, [key], value
              from yourtable
            ) x
            pivot 
            (
               max(value)
               for [key] in (' + @cols + ')
            ) p; '

exec sp_executesql @query;

请参阅SQL Fiddle with Demo