如何在动态查询数据透视表中使用CTE?

时间:2019-10-31 09:37:29

标签: sql sql-server-2008 pivot common-table-expression dynamicquery

我正在使用SQL Server 2008 R2

  • 首先,我需要将表1中的日期(开始日期和结束日期)划分为每天,这与递归CTE一样。
DECLARE @maxdate DATETIME = (SELECT Max([EndDate]) FROM table1);
WITH CTE_DateToDays
     AS (SELECT StartDate as Dates
         FROM   table1
         UNION ALL
         SELECT Dateadd(day, 1, Dates)
         FROM   CTE_DateToDays
         WHERE  Dates < @maxdate)

Select Dates from CTE_DateToDays;
  • 然后,我想将表2中的行转换为列。我不知道列数,所以使用了动态数据透视表。
DECLARE @TimeBandColms AS NVARCHAR(MAX);

        Select @TimeBandColms = STUFF((SELECT ',' + QUOTENAME(t.TimeBandName) 
                    from table2 t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');

Select @TimeBandColms
from
(
 SELECT t.TimeBandID,t.TimeBandName 
                        FROM
                      table2 t
) x
pivot
(
  MAX(TimeBandID)
  for TimeBandName in (" + @TimeBandColms + N")
) piv;

现在,每当我将这两件事结合在一起时,我就会陷入困境,有时结果集不是我想要的,或者有时出现“无效列名”或“无法绑定多部分标识符”的错误。

注意

  

表1和表2是不同的表,没有共同的地方,如键或ID。

我尝试了很多类似联合或其他方法的尝试,但无法解决我的问题。 抱歉,如果我没有更具体的说明,但是我对这个关键点,内容和CTE还是陌生的。 我真的需要你的帮助。

我想要的结果集是这样的... enter image description here

这是我的尝试。

DECLARE @TimeBandColms AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);
select @TimeBandColms = STUFF((SELECT ',' + QUOTENAME(t.TimeBandName) 
                    from table2 t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');

   set @query = 'DECLARE @maxdate DATETIME = (SELECT Max([EndDate]) FROM 
    table1);
   WITH CTE_DateToDays
     AS (SELECT StartDate as Dates
         FROM table1
         UNION ALL
         SELECT Dateadd(day, 1, Dates)
         FROM CTE_DateToDays
         WHERE  Dates < @maxdate)'


  Set @query += N'SELECT ' + @TimeBandColms + N' from 
             (
                SELECT CTE_DateToDays.Dates, t.TimeBandID,t.TimeBandName 
                        FROM CTE_DateToDays,
                      table2 t
            ) x
            pivot 
            (
               max(Dates)
  for TimeBandName in (' + @TimeBandColms + N')
            ) piv;'

exec (@query);

1 个答案:

答案 0 :(得分:0)

您可以尝试一下。

DECLARE @TimeBandColms AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);

select @TimeBandColms = STUFF((SELECT ',' + QUOTENAME(t.TimeBandName) 
                    from table2 t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');

   set @query = 'DECLARE @maxdate DATETIME = (SELECT Max([EndDate]) FROM 
    table1);
   WITH CTE_DateToDays
     AS (SELECT StartDate as Dates
         FROM table1
         UNION ALL
         SELECT Dateadd(day, 1, Dates)
         FROM CTE_DateToDays
         WHERE  Dates < @maxdate)'


  Set @query += N'SELECT Dates, ' + @TimeBandColms + N' from 
             (
                SELECT CTE_DateToDays.Dates, t.TimeBandID, t.TimeBandName 
                        FROM CTE_DateToDays
                            CROSS JOIN table2 t
            ) x
            pivot 
            (
               count(TimeBandID)
  for TimeBandName in (' + @TimeBandColms + N')
            ) piv;'

exec (@query);