Как преобразовать строки в данные с помощью T-SQL?

#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