Должен ли я использовать отдельный CROSS APPLY для каждого выражения с псевдонимом или определить несколько выражений в одном и том же CROSS APPLY, где это возможно?
Я рефакторинг многих очень сложных SQL-запросов (часто четыре или пять страниц длиной с дюжиной JOIN), которые генерируются в коде. Часто они вложены в пять или шесть запросов вглубь, так как некоторые части повторно используются в разных ситуациях. Типичная причина вложения запросов заключается в том, что один запрос извлекает некоторые значения, выполняет вычисления и присваивает псевдоним значению. Затем объемлющий запрос выполняет дальнейшие вычисления с использованием значения с псевдонимом и т. д. Это необходимо, поскольку на выражение с псевдонимом можно ссылаться только во внешнем запросе, а не где-либо еще в запросе, который его определяет. (Альтернатива, которая также присутствует в коде, состоит в том, чтобы повторять одно и то же длинное подвыражение десятки раз на протяжении всего запроса.)
Чтобы упростить этот спагетти-SQL, я начал сворачивать эти телескопические запросы с помощью CROSS APPLY. Используя CROSS APPLY, я могу назначить псевдоним и использовать его в другом месте того же запроса. Обратите внимание, что ни одно из моих предложений CROSS APPLY не вводит новые таблицы через подзапросы и не вызывает UDF.
Сначала я вложил много выражений в один и тот же CROSS APPLY. Однако мой код должен быть модульным. В разных ситуациях понадобятся разные поля, так как пользователи могут выбирать поля для фильтров, а мы генерируем одинаковую статистику для разных столбцов, следовательно, создаем много похожих запросов, мало отличающихся друг от друга. Поскольку некоторые поля основаны на других, а некоторые зависят от определенных JOIN, определенных ранее в запросе, я не могу поместить все в один и тот же CROSS APPLY. Следовательно, количество CROSS APPLY может варьироваться.
Кроме того, некоторые поля, которые извлекаются из, затеняются новыми псевдонимами и переопределяются (обычно для удаления значений NULL, предоставления значений по умолчанию и т. д.). убрать двусмысленность.
В результате мне нужен логический способ назвать мои CROSS APPLY, и я забочусь о производительности. Если количество CROSS APPLY изменяется, то, если CROSS APPLY нумеруются с помощью простого счетчика (например, вычислено1, вычислено2 и т. д.), то данное поле может увидеть изменение ссылки на свое имя с вычисляемого3.[ИМЯ ПОЛЯ] на вычисляемое4.[ПОЛЕ]. NAME], который влияет на всю оставшуюся часть запроса, который мог быть собран путем вызовов различных процедур C#. Это проблема технического обслуживания.
Альтернативой, которую я рассматриваю, является размещение каждого вычисляемого выражения в отдельном CROSS APPLY, а имя CROSS APPLY будет получено из псевдонима выражения. Например:
Использование одного CROSS APPLY:
CROSS APPLY (
SELECT
[TIV_BLDG] = (CASE [COVERAGE] WHEN 'TIV_BLDG' THEN VALUEAMT ELSE 0 END)
, [TIV_OSTR] = (CASE [COVERAGE] WHEN 'TIV_OSTR' THEN VALUEAMT ELSE 0 END)
, [TIV_CONT] = (CASE [COVERAGE] WHEN 'TIV_CONT' THEN VALUEAMT ELSE 0 END)
, [TIV_TIME] = (CASE [COVERAGE] WHEN 'TIV_TIME' THEN VALUEAMT ELSE 0 END)
) computed2
Используя четыре CROSS APPLY:
CROSS APPLY (SELECT [TIV_BLDG] = (CASE [COVERAGE] WHEN 'TIV_BLDG' THEN VALUEAMT ELSE 0 END)) AS [TIV_BLDG_COMP]
CROSS APPLY (SELECT [TIV_OSTR] = (CASE [COVERAGE] WHEN 'TIV_OSTR' THEN VALUEAMT ELSE 0 END)) AS [TIV_OSTR_COMP]
CROSS APPLY (SELECT [TIV_CONT] = (CASE [COVERAGE] WHEN 'TIV_CONT' THEN VALUEAMT ELSE 0 END)) AS [TIV_CONT_COMP]
CROSS APPLY (SELECT [TIV_TIME] = (CASE [COVERAGE] WHEN 'TIV_TIME' THEN VALUEAMT ELSE 0 END)) AS [TIV_TIME_COMP]
Если я использую этот подход с несколькими CROSS APPLY, я могу легко генерировать имена, которые не изменятся, если я добавлю новые приложения или удалю их, и я могу предсказать в коде, который ссылается на поля, каким будет псевдоним таблицы. Однако это означает гораздо больше операторов CROSS APPLY. Каковы последствия производительности? Есть ли лучший способ сделать это, используя CROSS APPLY или какую-либо другую функцию SQL Server? (Мне не нужно, чтобы это была кросс-база данных, поэтому функции только Microsoft в порядке.)