Как мне просто переключать столбцы со строками в SQL? Есть ли простая команда для транспонирования?
т.е. превратить этот результат:
Paul | John | Tim | Eric
Red 1 5 1 3
Green 8 4 3 5
Blue 2 2 9 1
в это:
Red | Green | Blue
Paul 1 8 2
John 5 4 2
Tim 1 3 9
Eric 3 5 1
PIVOT
кажется слишком сложным для этого сценария.
sql
sql-server
tsql
pivot
Эдеззи
источник
источник
Ответы:
Эти данные можно преобразовать несколькими способами. В исходном сообщении, вы заявили , что
PIVOT
кажется слишком сложным для этого сценария, но он может быть применен очень легко , используя какUNPIVOT
иPIVOT
функцию в SQL Server.Однако, если у вас нет доступа к этим функциям, их можно воспроизвести с помощью функции
UNION ALL
to,UNPIVOT
а затем агрегатной функции сCASE
инструкцией дляPIVOT
:Создать таблицу:
Версия Union All, Aggregate и CASE:
См. SQL Fiddle с демонстрацией
В
UNION ALL
выполн етUNPIVOT
из данных путем преобразования столбцовPaul, John, Tim, Eric
в отдельные строки. Затем вы применяете агрегатную функциюsum()
сcase
оператором, чтобы получить новые столбцы для каждогоcolor
.Статическая версия Unpivot и Pivot:
Оба
UNPIVOT
иPIVOT
функция в сервере SQL сделать это преобразование гораздо проще. Если вы знаете все значения, которые хотите преобразовать, вы можете жестко закодировать их в статическую версию, чтобы получить результат:Видеть SQL Fiddle с демонстрацией
Внутренний запрос с
UNPIVOT
классом выполняет ту же функцию, что иUNION ALL
. Он берет список столбцов и превращает его в строки,PIVOT
затем выполняет окончательное преобразование в столбцы.Версия Dynamic Pivot:
Если у вас есть неизвестное количество столбцов (
Paul, John, Tim, Eric
в вашем примере), а затем неизвестное количество цветов для преобразования, вы можете использовать динамический sql для создания списка,UNPIVOT
а затемPIVOT
:Видеть SQL Fiddle с демонстрацией
Динамическая версия запрашивает обе,
yourtable
а затемsys.columns
таблицу для создания списка элементов дляUNPIVOT
иPIVOT
. Затем он добавляется в строку запроса для выполнения. Плюс динамической версии в том, что у вас есть изменяющийся списокcolors
и / илиnames
он будет генерировать список во время выполнения.Все три запроса дадут одинаковый результат:
источник
Обычно это требует, чтобы вы знали ВСЕ метки столбцов И строк заранее. Как вы можете видеть в запросе ниже, все метки перечислены полностью как в операциях UNPIVOT, так и в операциях (re) PIVOT.
Настройка схемы MS SQL Server 2012 :
Запрос 1 :
Результаты :
Дополнительные замечания:
источник
Я хотел бы указать еще несколько решений для транспонирования столбцов и строк в SQL.
Первый - с помощью КУРСОРА. Хотя общее мнение в профессиональном сообществе состоит в том, чтобы держаться подальше от курсоров SQL Server, все же есть случаи, когда использование курсоров рекомендуется. В любом случае курсоры предоставляют нам еще одну возможность транспонировать строки в столбцы.
Вертикальное расширение
Подобно PIVOT, курсор имеет динамическую возможность добавлять больше строк по мере того, как ваш набор данных расширяется и включает больше номеров политик.
Горизонтальное расширение
В отличие от PIVOT, курсор выделяется в этой области, так как он может расширяться для включения недавно добавленного документа без изменения сценария.
Анализ производительности
Основным ограничением транспонирования строк в столбцы с помощью CURSOR является недостаток, связанный с использованием курсоров в целом - они требуют значительных затрат производительности. Это связано с тем, что Cursor генерирует отдельный запрос для каждой операции FETCH NEXT.
Еще одно решение перестановки строк в столбцы - использование XML.
Решение XML для транспонирования строк в столбцы в основном является оптимальной версией PIVOT, поскольку оно устраняет ограничение динамического столбца.
Версия сценария XML устраняет это ограничение, используя комбинацию XML Path, динамического T-SQL и некоторых встроенных функций (например, STUFF, QUOTENAME).
Вертикальное расширение
Подобно PIVOT и Cursor, новые добавленные политики можно получить в XML-версии сценария без изменения исходного сценария.
Горизонтальное расширение
В отличие от PIVOT, недавно добавленные документы могут отображаться без изменения сценария.
Анализ производительности
Что касается ввода-вывода, статистика XML-версии сценария почти аналогична PIVOT - с той лишь разницей, что XML имеет второе сканирование таблицы dtTranspose, но на этот раз из кэша логических данных для чтения.
Вы можете найти больше об этих решениях (включая некоторые актуальные примеры T-SQL) в этой статье: https://www.sqlshack.com/multiple-options-to-transposing-rows-into-columns/
источник
На основе этого решения от bluefeet представлена хранимая процедура, которая использует динамический sql для создания транспонированной таблицы. Требуется, чтобы все поля были числовыми, кроме транспонированного столбца (столбца, который будет заголовком в результирующей таблице):
Вы можете проверить это с помощью таблицы, предоставленной с помощью этой команды:
источник
Я делаю
UnPivot
сначала, сохраняю результатыCTE
и используюCTE
вPivot
работе.Демо
источник
Добавляя к потрясающему ответу @Paco Zarate выше, если вы хотите транспонировать таблицу, которая имеет несколько типов столбцов, добавьте это в конец строки 39, чтобы она перемещала только
int
столбцы:Вот полный изменяемый запрос:
Чтобы найти другие
system_type_id
, запустите это:источник
Мне нравится делиться кодом, который я использую для транспонирования разделенного текста на основе ответа + bluefeet. В этом подходе я реализован как процедура в MS SQL 2005
Я смешиваю это решение с информацией о том, как упорядочить строки без упорядочения по ( SQLAuthority.com ) и функцией разделения на MSDN ( social.msdn.microsoft.com )
Когда вы выполняете prodecure
вы получите следующий результат
источник
Таким образом преобразовать все данные из файлов (столбцов) в таблицу в запись (строку).
источник
Я смог использовать решение Пако Зарате, и оно прекрасно работает. Мне пришлось добавить одну строку («SET ANSI_WARNINGS ON»), но это может быть чем-то уникальным для того, как я ее использовал или называл. Возникла проблема с моим использованием, и я надеюсь, что кто-нибудь сможет мне с этим помочь:
Решение работает только с реальной таблицей SQL. Я пробовал это с временной таблицей, а также с таблицей (объявленной) в памяти, но она не работает с ними. Поэтому в вызывающем коде я создаю таблицу в своей базе данных SQL, а затем вызываю SQLTranspose. Опять же, отлично работает. Это то, чего я хочу. Вот моя проблема:
Чтобы общее решение было действительно динамичным, мне нужно создать эту таблицу, в которой я временно храню подготовленную информацию, которую я отправляю в SQLTranspose «на лету», а затем удалить эту таблицу после вызова SQLTranspose. Удаление таблицы представляет проблему с моим окончательным планом реализации. Код должен запускаться из приложения конечного пользователя (кнопка в форме / меню Microsoft Access). Когда я использую этот процесс SQL (создаю таблицу SQL, вызываю SQLTranspose, удаляю таблицу SQL), приложение конечного пользователя выдает ошибку, потому что используемая учетная запись SQL не имеет прав на удаление таблицы.
Я полагаю, что есть несколько возможных решений:
Найдите способ заставить SQLTranspose работать с временной таблицей или объявленной табличной переменной.
Придумайте еще один метод перестановки строк и столбцов, который не требует реальной таблицы SQL.
Найдите подходящий метод, позволяющий учетной записи SQL, используемой моими конечными пользователями, удалять таблицу. Это единственная общая учетная запись SQL, закодированная в моем приложении Access. Похоже, что разрешение - это привилегия типа dbo, которую нельзя предоставить.
Я понимаю, что некоторые из них могут потребовать другой, отдельной темы и вопроса. Однако, поскольку есть вероятность, что одно решение может быть просто другим способом транспонирования строк и столбцов, я сделаю свой первый пост здесь, в этой теме.
РЕДАКТИРОВАТЬ: Я также заменил sum (value) на max (value) в 6-й строке с конца, как предложил Пако.
РЕДАКТИРОВАТЬ:
Я понял кое-что, что мне подходит. Не знаю, лучший это ответ или нет.
У меня есть учетная запись пользователя, доступная только для чтения, которая используется для выполнения хранимых процедур и, следовательно, для создания отчетов из базы данных. Поскольку созданная мною функция SQLTranspose будет работать только с «законной» таблицей (не с объявленной таблицей и не с временной таблицей), мне пришлось найти способ для учетной записи пользователя, доступной только для чтения, для создания (а затем последующего удаления) таблицы. .
Я рассудил, что для моих целей разрешено создавать таблицу для учетной записи пользователя. Однако пользователь все еще не может удалить таблицу. Мое решение заключалось в создании схемы, в которой учетная запись пользователя авторизована. Затем всякий раз, когда я создаю, использую или удаляю эту таблицу, обращайтесь к ней с указанной схемой.
Сначала я ввел эту команду из учетной записи 'sa' или 'sysadmin': CREATE SCHEMA ro AUTHORIZATION
Каждый раз, когда я обращаюсь к своей таблице "tmpoutput", я указываю ее следующим образом:
сбросить таблицу ro.tmpoutput
источник