Как использовать CTE с динамическим сводным запросом? - PullRequest
0 голосов
/ 31 октября 2019

Я использую 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;

Теперь я застреваю, когда объединяю эти две вещи, иногда набор результатов - это не то, что я хочу, или иногда ошибка с «Неверное имя столбца» или «Не удалось определить идентификатор из нескольких частей». be be '.

ПРИМЕЧАНИЕ

Table1 и Table2 - это разные таблицы, не имеющие ничего общего, например, ключ или идентификатор.

Я пробовал много вещей, таких как объединение или другой подход, но не смог решить мою проблему. Извините, если я не более конкретен, но я новичок в этом стержне, материале и 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 голосов
/ 02 ноября 2019

Вы можете попробовать это.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...