Динамическая сводка с множественными значениями SQL

Ниже у меня есть мой текущий код.

Что я пытаюсь сделать в этом коде:

Таблица #BySite содержит список записей, в котором все столбцы, перечисленные перед столбцом PlayMonth, представляют собой моментальный снимок в конце каждого месяца с 1.10.2021. Столбцы PlayMonth вплоть до Actual — это значения за каждый месяц с 01.10.2021. Например, если у игрока есть записи за период с января 2024 года по март 2024 года, то будет 3 записи за январь 2024 года, одна с данными воспроизведения за месяцы январь, февраль и март. Будет 2 записи за февраль 2024 года, одна с данными воспроизведения за февраль и март. Март. И в настоящее время будет 1 запись для марта, содержащая только данные воспроизведения за март. Когда пройдет новый месяц, каждый из этих месяцев получит новую запись за апрель. Вместо добавления новых строк. Я хочу преобразовать строки в динамический набор столбцов, чтобы у этого игрока было 3 строки для января, февраля и марта. Столбцы будут расширяться и иметь вид Jan_Theo, Jan_Acutal, Feb_Theo, Feb_Actual, Mar_Theo, Mar_Actual. и когда апрель закончится, Apr_Theo, Apr_Actual. Значения будут нулевыми для месяцев, предшествующих этому месяцу строк. Кроме того, я тестировал только два значения с опорной точкой, но добавлю еще несколько. ClubLevel, Property, Trips, Theo, Actual, FP — это полный список столбцов, которые необходимо повернуть.

Что я пытаюсь сделать в целом, если есть лучший способ подойти к этому:

Цель состоит в том, чтобы иметь возможность сравнивать действия любого игрока за один месяц с другим в отчете, где конечный пользователь может выбрать любые два месяца и сравнить их.

DECLARE @cols AS NVARCHAR(MAX)
DECLARE @Query AS NVARCHAR(MAX)

SELECT @cols = STUFF((
    SELECT ',' + QUOTENAME(PlayMonth)
    FROM (
        SELECT DISTINCT CAST(BS.Playyear AS VARCHAR(20)) + '|' + CAST(BS.PlayMonth AS VARCHAR(20)) AS PlayMonth
        FROM #BySite AS BS
    ) AS PivotColumns
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @Query = '
SELECT *
FROM (
    SELECT BS.EndingClubLevel
        , BS.PropertyName
        , BS.Year
        , BS.Month
        , BS.Universal_ID
        , BS.Old_Trips
        , BS.Old_Theo
        , BS.Old_Actual
        , BS.Old_FP
        , CAST(BS.Playyear AS VARCHAR(20)) + ''|'' + CAST(BS.PlayMonth AS VARCHAR(20)) AS PlayMonth
        , BS.CurrentClubLevel as ClubLevel
        , BS.PlayProperty as Property
        , BS.Trips
        , BS.theo
        , BS.Actual
        ,BS.FP
    FROM #BySite AS BS
) AS Src

PIVOT (
    AVG(theo) FOR PlayMonth IN (' + @cols + ')
) AS TheoPivot
PIVOT (
    AVG(Actual) FOR PlayMonth IN (' + @cols + ')
) AS ActualPivot';

EXEC sp_executesql @Query;

Обновлено: образец данных был запрошен вместе с желаемым результатом, и это имеет смысл, поэтому ниже это показано. Я обозначил его цветом, чтобы попытаться объяснить. Есть записи для двух игроков: один светло-оранжевого цвета, другой серого. Зеленые заголовки — это статические заголовки, представляющие собой снимки за определенный месяц. Фиолетовые заголовки содержат значения за каждый месяц, и именно их я хотел динамически развернуть. Это сделает раздел результатов очень широким после работы и будет постоянно расширяться на 6 столбцов в месяц.

Редактировать2:

Если я запускаю код с закомментированными ClubLevel, Property, Trips, Actual и FP, а второй опорный элемент закомментирован, он работает так, как ожидалось/желалось. Когда я добавляю обратно фактический столбец и опорную точку для фактического значения, я получаю следующую ошибку. это продолжается для каждой комбинации месяца и года.

Я пытаюсь создать что-то похожее на то, что я вижу в примере min, max с этого сайта SQL Pivot

Я понимаю, что в этом примере они просто выполнили один поворот с несколькими значениями, но мне тоже не удалось заставить его работать без ошибок.

Msg 207, Level 16, State 1, Line 129
Invalid column name 'PlayMonth'.
Msg 265, Level 16, State 1, Line 129
The column name "2021|11" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
Msg 265, Level 16, State 1, Line 129
The column name "2021|12" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.

Так что же вы вообще здесь спрашиваете? А что насчет того, что у тебя не работает? Можете ли вы предоставить данные образцов расходных материалов и ожидаемые результаты?

Thom A 06.04.2024 19:36

Приятно, когда вы объясняете свои данные, но зачастую проще поместить данные в табличный формат или, что еще лучше, в сценарий sql, чтобы люди могли с ними работать. Также ожидаемые результаты необходимо прикрепить в виде таблицы.

siggemannen 06.04.2024 20:44

Нам нужен минимальный воспроизводимый пример с упором на минимальный

Dale K 06.04.2024 22:02

@ThomA Я добавил образец и желаемые результаты, надеюсь, это поможет.

Chad Portman 06.04.2024 22:47

@siggemannen Я не знаю, как опубликовать это в формате таблицы, поэтому я сделал фотографии, надеюсь, это поможет. Если вы дадите мне какое-то руководство о том, как публиковать сообщения в нужном вам формате, я его создам.

Chad Portman 06.04.2024 22:48

Вы искали, как добавить уценку таблицы ?

Dale K 07.04.2024 00:50

Это изображения, они не расходуются, @ChadPortman, и поэтому бесполезны.

Thom A 07.04.2024 07:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я смог найти ответ. Мне пришлось выделить каждый столбец в отдельную переменную и использовать ее в сводных таблицах, чтобы все столбцы имели уникальные имена.

DECLARE @Theo AS NVARCHAR(MAX)
DECLARE @Actual AS NVARCHAR(MAX)
DECLARE @Query AS NVARCHAR(MAX)

SELECT @Theo = STUFF((
    SELECT ',' + QUOTENAME(TheoBreakout)
    FROM (
        SELECT DISTINCT CAST(BS.Playyear AS VARCHAR(20)) + '|' + CAST(BS.PlayMonth AS VARCHAR(20))+ '|Theo' AS TheoBreakout
        FROM #BySite AS BS
    ) AS PivotColumns
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SELECT @Actual = STUFF((
    SELECT ',' + QUOTENAME(ActualBreakout)
    FROM (
        SELECT DISTINCT CAST(BS.Playyear AS VARCHAR(20)) + '|' + CAST(BS.PlayMonth AS VARCHAR(20)) + '|Actual' AS ActualBreakout
        FROM #BySite AS BS
    ) AS PivotColumns
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @Query = '
SELECT *
FROM (
    SELECT BS.EndingClubLevel
        , BS.PropertyName
        , BS.Year
        , BS.Month
        , BS.Universal_ID
        , BS.Old_Trips
        , BS.Old_Theo
        , BS.Old_Actual
        , BS.Old_FP
        , CAST(BS.Playyear AS VARCHAR(20)) + ''|'' + CAST(BS.PlayMonth AS VARCHAR(20))+ ''|Theo'' AS TheoBreakout
        , CAST(BS.Playyear AS VARCHAR(20)) + ''|'' + CAST(BS.PlayMonth AS VARCHAR(20)) + ''|Actual'' AS ActualBreakout
        --, BS.CurrentClubLevel
        
      --  , BS.PlayProperty
        , BS.theo
       , BS.Actual
    FROM #BySite AS BS
) AS Src

PIVOT (
    AVG(theo) FOR TheoBreakout IN (' + @Theo + ')
) AS TheoPivot
PIVOT (
    AVG(Actual) FOR ActualBreakout IN (' + @Actual + ')
) AS ActualPivot'

EXEC sp_executesql @Query;

Другие вопросы по теме