【问题标题】:Dynamic pivot query in sql serversql server 中的动态数据透视查询
【发布时间】:2015-01-19 17:27:57
【问题描述】:

我有一个针对静态列值的有效数据透视查询,我想将其转换为动态列值。

查询是:

with a as (

select  request_id, dateadd(month,datediff(month,0,logged_datetime),0) as 'Month'
,dateadd(month,datediff(month,0,logged_datetime),0) as 'Year'

 from requests

 )


 select  * from (

 select datepart(m,a.Month) as 'months',datepart(YEAR,a.Year) as 'years',a.request_id

  from a  ) ps

 pivot (

 count(request_id) for [years] in ([2008],[2009],[2010],[2011],[2012],[2013],[2014],[2015])
 ) as pvt
 order by months

对于下面编写的动态查询,我遇到了类似

的错误

消息 207,级别 16,状态 1,第 5 行无效的列名称“2010”。 :

select distinct datepart(year,dateadd(month,datediff(month,0,logged_datetime),0)) as 'Yearz'

into #t

FROM requests

DECLARE @Dynamic AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)

SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
       + QUOTENAME(Yearz)
FROM (SELECT * from #t) AS Yea


SET @Dynamic = 
  N'

 select  * from (

 select datepart(m,dateadd(month,datediff(month,0,logged_datetime),0)) as months,' + @ColumnName + ',request_id

  from requests ) ps

 pivot (

 count(request_id) for [Years] in (' + @ColumnName + ')
 ) as pvt
 order by months
'

EXEC sp_executesql @Dynamic

【问题讨论】:

  • 那是什么问题
  • @NoDisplayName 我尝试的动态查询不起作用。出现错误。
  • 发现它从数据中心源查询中删除了 ` + @ColumnName + `。试试这个。..select datepart(m,dateadd(month,datediff(month,0,logged_datetime),0)) as months,request_id from requests ..

标签: sql sql-server dynamic-sql


【解决方案1】:

示例表

SELECT * INTO #REQUESTS
FROM
(
    SELECT 1 request_id, '2012-06-01' logged_datetime
    UNION ALL
    SELECT 2 request_id,  '2012-05-01'
    UNION ALL
    SELECT 11 request_id, '2012-06-01' 
    UNION ALL
    SELECT 12 request_id,  '2012-05-01'
    UNION ALL
    SELECT 3 request_id,  '2012-07-01' 
    UNION ALL
    SELECT 4 request_id,  '2013-09-01' 
    UNION ALL
    SELECT 5 request_id,  '2013-10-01' 
    UNION ALL
    SELECT 6 request_id, '2014-01-01' 
    UNION ALL
    SELECT 7 request_id,  '2014-02-01' 
    UNION ALL
    SELECT 8 request_id, '2014-03-01' 
    UNION ALL
    SELECT 9 request_id,  '2014-05-01' 
    UNION ALL
    SELECT 10 request_id,  '2015-11-01' 
)TAB

查询

获取years 的列并按数字顺序对其进行排序

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + CAST([YEAR] AS VARCHAR(4)) + ']',  '[' + CAST([YEAR] AS VARCHAR(4)) + ']')
               FROM    (SELECT DISTINCT YEAR(dateadd(month,datediff(month,0,logged_datetime),0)) [YEAR] FROM #REQUESTS) PV  
               ORDER BY CAST([YEAR] AS INT)

现在旋转查询

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             ( 
                 -- We will get the count for a year and number of request_id in that month here as CNT column
                 select DISTINCT datepart(m,a.Month) as ''months'',datepart(YEAR,a.Year) as ''years'',
                COUNT(*) OVER(PARTITION BY datepart(YEAR,a.Year),datepart(m,a.Month)) CNT
                 from
                 (
                    select  request_id, dateadd(month,datediff(month,0,logged_datetime),0) as ''Month''
                    ,dateadd(month,datediff(month,0,logged_datetime),0) as ''Year''
                     from #requests
                 )a 
             ) x
             PIVOT 
             (
                 MIN(CNT)
                 FOR years IN (' + @cols + ')
            ) p
            ORDER BY MONTHS;' 

EXEC SP_EXECUTESQL @query

【讨论】:

    【解决方案2】:

    我认为您需要使用 QUOTENAME 函数来包装动态列名:

    见例子here

    【讨论】:

    • Quotename 被使用。 + QUOTENAME(Yearz) FROM (SELECT * from #t)
    猜你喜欢
    • 2016-10-28
    • 1970-01-01
    • 2014-10-16
    • 2014-07-26
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    相关资源
    最近更新 更多