Поворотные таблицы в SQL Server в 2019 году и в будущем - PullRequest
0 голосов
/ 24 мая 2019

Есть ли способы добиться динамического поворота таблиц в SQL Server с помощью элегантной функции?Поворотные таблицы - это базовая утилита, которая теоретически может быть выполнена в одной строке кода.Все, что нам нужно, это определить параметры: переменная столбца для сводки (изменить ее значения на имена столбцов), переменная для агрегирования, функция агрегирования и таблица, для которой мы выполняем поворот.

Я ищу альтернативы синтаксисуMicrosoft предлагает поворотные таблицы в SQL Server в 2019 году.

Практическая альтернатива, которую я нашел здесь: https://stackoverflow.com/a/45065584/1903793

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

exec [dbo].[USP_DYNAMIC_PIVOT] 'date','category','amount','dbo.temp','sum'

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

Обновление после комментариев. Пока я не начал использовать SQL Server, я даже не знал, что поворот может быть статическим.Нужно сделать динамическое вращение.Многие другие приложения выполняют поворот таблиц на лету (Excel, Power BI, R) без ограничения того, что имена столбцов должны быть известны в первую очередь.В 2005 году может возникнуть проблема с осознанием того, что поворот может выполняться как функция с параметрами.Но, эй, мы идем в будущее, и смешно, что мы движемся в следующие десятилетия со сложным ограниченным синтаксисом для этой основной утилиты преобразования таблиц.

Ответы [ 4 ]

3 голосов
/ 24 мая 2019

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

Я не понимаю этого. Имя таблицы является одним из аргументов, поэтому для этого не требуется «статическая таблица».

Что еще более важно, хранимая процедура не может быть написана как (разумная) пользовательская функция, потому что она требует динамического SQL. А пользовательские функции не поддерживают динамический SQL.

Вы также должны понимать, что все, что содержится в предложении FROM, требует, чтобы столбцы и типы столбцов были известны на этапе компиляции запроса . Это исключает использование строк для указания имен столбцов, поскольку строка может быть параметром.

2 голосов
/ 30 мая 2019

SQL Server - это реляционная система управления базами данных. Концепция отношения лежит в основе его дизайна. Все системы управления реляционными базами данных спроектированы исходя из предположения, что схема базы данных стабильна. Другими словами, все РСУБД предполагают, что список таблиц и их столбцов являются статическими. Они предназначены для эффективной работы, когда данные структурированы таким образом.

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

У меня нет опыта работы с нереляционными СУБД. В настоящее время их множество, и некоторые из них лучше подходят для ваших задач, чем RDBMS.

В СУБД часто происходит разделение данных и их представление конечному пользователю.

Задача СУБД состоит в том, чтобы эффективно находить и объединять необходимые подмножества данных в большой базе данных, которая находится на сервере, и возвращать небольшой набор результатов клиенту. Задача инструмента создания клиентских отчетов состоит в том, чтобы взять этот результирующий набор данных и отформатировать его так, как этого хочет конечный пользователь. Например, показывать знак доллара перед денежными суммами, округлять значения с необходимой точностью, распечатывать значения в виде перекрестных таблиц с промежуточными итогами и т. Д. Поворот является распространенной широко распространенной потребностью, и существует множество инструментов отчетности, которые могут форматируйте небольшие подмножества данных любым удобным для вас способом, но эти инструменты не являются системами управления базами данных.


Да, СУБД в целом и SQL Server в частности имеют некоторые возможности для работы с динамической схемой базы данных, но они часто бывают неуклюжими и уродливыми, такими как динамический SQL и синтаксис PIVOT. Они не были предназначены для этого.

2 голосов
/ 24 мая 2019

Excel на самом деле не выполняет динамическую сводку полностью - вам все равно нужно указать порядок поворотных столбцов или псевдоним имен столбцов, используя графический интерфейс для тонкой окончательной презентации (хотя в некоторых ограниченных случаях это не имеет значения) ,

Вы также (насколько я помню) не можете в Excel указать столбцы, заголовки которых вообще не существуют в исходных данных - в некоторых случаях вы должны включать фиктивные строки в источнике, просто чтобы заставить определенный столбец присутствовать в выводе сводки (хотя значения в таком столбце все будут нулевыми или пустыми, но в окончательных отчетах часто важно сказать об этом явно и / или сохранить визуальную структуру сводки).

Очевидно, что SQL требует, чтобы все это было сделано заранее в самом коде.

Я согласен с тем, что синтаксис SQL - это ямы, но, честно говоря, если только порядок столбцов не имеет значения, имена столбцов не требуют псевдонимов и не требуется наличия определенного столбца (тройной критерий, который не выполняется в В подавляющем большинстве случаев динамический разворот был бы полезен), тогда я не понимаю, как еще можно решить проблему.

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

0 голосов
/ 31 мая 2019

Вы можете использовать динамические запросы SQL и выполнить желаемый результат в одном запросе.Но сначала мы подготовим разные компоненты нашего запроса в разных переменных, а затем объединим их все вместе, чтобы сделать один запрос в соответствии с желаемым результатом вывода.

Вы объявите свой запрос в переменной типа @query типа varchar.Добавив в свой запрос другой компонент, вы создадите любой динамический запрос, который не зависит от отдельной таблицы, но выполняет аналогичные операции для любого имени таблицы или передаваемых в нее параметров.

После создания запроса вы можете выполнить егос помощью exec или exec sp_executesql и получите желаемый результат.

...