Мне было поручено придумать способ перевода следующих данных:
date category amount
1/1/2012 ABC 1000.00
2/1/2012 DEF 500.00
2/1/2012 GHI 800.00
2/10/2012 DEF 700.00
3/1/2012 ABC 1100.00
в следующее:
date ABC DEF GHI
1/1/2012 1000.00
2/1/2012 500.00
2/1/2012 800.00
2/10/2012 700.00
3/1/2012 1100.00
Пустые места могут быть NULL или пробелами, либо в порядке, и категории должны быть динамическими. Еще одно возможное предостережение: мы будем выполнять запрос с ограниченными возможностями, что означает, что временные таблицы отсутствуют. Я пытался исследовать и приземлился, PIVOT
но поскольку я никогда не использовал это прежде, я действительно не понимаю это, несмотря на все мои усилия, чтобы понять это. Может кто-то указать мне верное направление?
sql
sql-server
tsql
pivot
Шон Каннингем
источник
источник
Ответы:
Динамический SQL PIVOT:
Полученные результаты:
источник
@cols
вы можете удалитьDISTINCT
и использовать,GROUP BY
иORDER BY
когда вы получите список@cols
.Динамический SQL PIVOT
Другой подход к созданию строки столбцов
результат
источник
Я знаю, что этот вопрос старше, но я искал ответы и думал, что смогу раскрыть «динамическую» часть проблемы и, возможно, помочь кому-нибудь.
Прежде всего, я построил это решение для решения проблемы, возникшей у пары коллег с непостоянными и большими наборами данных, которые необходимо быстро поворачивать.
Это решение требует создания хранимой процедуры, поэтому, если об этом не идет речь, пожалуйста, прекратите чтение.
Эта процедура будет принимать ключевые переменные оператора сводки для динамического создания операторов сводки для переменных таблиц, имен столбцов и агрегатов. Столбец Static используется в качестве столбца group by / identity для сводной таблицы (его можно удалить из кода, если в этом нет необходимости, но он довольно распространен в операторах сводной таблицы и был необходим для решения исходной проблемы), где в столбце сводной таблицы конечные результирующие имена столбцов будут сгенерированы, а столбец значений - это то, к чему будет применяться агрегат. Параметр Table - это имя таблицы, включая схему (schema.tablename), которую эта часть кода может использовать с любовью, потому что она не так чиста, как хотелось бы. Это работало для меня, потому что мое использование не было публично, и инъекция sql не была проблемой.
Давайте начнем с кода для создания хранимой процедуры. Этот код должен работать во всех версиях SSMS 2005 и выше, но я не проверял его в 2005 или 2016 году, но не могу понять, почему он не будет работать.
Далее мы подготовим наши данные для примера. Я взял пример данных из принятого ответа с добавлением пары элементов данных для использования в этом доказательстве концепции, чтобы показать различные результаты совокупного изменения.
В следующих примерах показаны различные операторы выполнения, показывающие различные агрегаты в качестве простого примера. Я не решил изменять столбцы static, pivot и value, чтобы сделать пример простым. Вы должны быть в состоянии просто скопировать и вставить код, чтобы начать возиться с ним самостоятельно
Это выполнение возвращает следующие наборы данных соответственно.
источник
Обновленная версия для SQL Server 2017, использующая функцию STRING_AGG для построения списка сводных столбцов:
источник
Вы можете добиться этого с помощью динамического TSQL (не забудьте использовать QUOTENAME, чтобы избежать атак с использованием SQL-инъекций):
Сводки с динамическими столбцами в SQL Server 2005
SQL Server - динамическая таблица PIVOT - инъекция SQL
Обязательная ссылка на Проклятие и благословения динамического SQL
источник
QUOTENAME
помогает атаковать с помощью SQL-инъекций только в том случае, если вы принимаете @tableName в качестве параметра от пользователя и добавляете его в запрос типаSET @sql = 'SELECT * FROM ' + @tableName;
. Вы можете создать множество уязвимых динамических строк SQL, и вамQUOTENAME
это не поможет.Вот мое решение, очищающее ненужные нулевые значения
источник
Приведенный ниже код предоставляет результаты, которые заменяют NULL на ноль в выходных данных.
Создание таблицы и вставка данных:
Запрос для получения точных результатов, который также заменяет NULL нулями:
ВЫВОД :
источник