#sql-server #tsql #pivot
#sql-сервер #tsql #сводная
Вопрос:
У меня есть следующие данные:
code desc amt month
----- ---------- ----- ------
aa item aa 12 4/2019
aa item aa 7 5/2019
bb item bb 5 4/2019
bb item bb 35 5/2019
bc widget bc 109 3/2019
bc widget bc 100 4/2019
df widget df 29 5/2019
Я хочу преобразовать эти данные так, чтобы они выглядели так:
code desc 3/2019 4/2019 5/2019
----- ---------- -------- -------- --------
aa item aa 0 12 7
bb item bb 0 5 35
bc widget bc 109 100 0
df widget df 0 0 29
Все примеры pivot, которые я вижу, включают функции агрегирования, но я не хочу агрегировать, мне просто нужно объединить / перенести данные. Как я могу это сделать?
Комментарии:
1. вы можете использовать MIN или MAX для псевдоагрегации, если у вас есть уникальная строка для каждого месяца
2. @Vasya Я думаю, что в этом случае они не будут уникальными, поскольку этот столбец является «суммой».
3. Нет, это уникальные записи для каждого «элемента» и «месяца». Например, существует только одна строка «4/2019» для кода «aa».
4. Если вы заранее не знаете, какие месяцы вам нужны, вы можете ознакомиться с этим советом, чтобы получить некоторые идеи о построении динамических сводных запросов: mssqltips.com/sqlservertip/2783 /…
5. Итак, я изучил эти предложения и понял, что мне также нужно вывести столбцы, и я придумал это: dbfiddle.uk/… Не самое элегантное решение, но оно работает! Спасибо всем!
Ответ №1:
Предполагая, что вам нужны динамические столбцы … тогда вам понадобится немного динамического SQL
Пример
Declare @SQL varchar(max) = '
Select *
From YourTable
Pivot (sum(amt) For [month] in (' Stuff((Select Distinct ',' QuoteName(month)
From YourTable A
Order By 1
For XML Path('')),1,1,'') ') ) p'
Exec(@SQL);
--Print @SQL
ВОЗВРАТ
Динамический SQL выглядит следующим образом
Select *
From YourTable
Pivot (sum(amt) For [month] in ([3/2019],[4/2019],[5/2019]) ) p
Комментарии:
1. Они должны быть динамическими (новый столбец будет добавляться каждый месяц). Это хорошая отправная точка для того, что мне нужно…
2. Это идеально подходило для моих нужд, поскольку я смог присоединить его к другому представлению в хранимой процедуре, чтобы сгенерировать результирующий набор, необходимый для моего отчета. Спасибо!
3. @EricBelair Конечно. Один из методов заключается в создании второго списка имен столбцов, который будет выдавать …, [3/2019] = isnull([3/2019],0) … Или мой предпочтительный метод — создать вложенный запрос, который генерирует пересечение комбинаций данных. Дайте мне несколько, и я создам отправлю вам dbfiddle
4. @EricBelair Взгляните на dbfiddle.uk/… Обратите внимание на подзапрос src с ОБЪЕДИНЕНИЕМ ALL
5. @EricBelair Второй вариант с использованием IsNull() dbfiddle.uk /…
Ответ №2:
Существует функция pivot, которую вы можете напрямую использовать в T-sql, попробуйте это https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017