#sql #sql-server #cross-apply
#sql #sql-server #перекрестное применение
Вопрос:
Я работаю над хранимой процедурой, которую я унаследовал, и у нее есть несколько перекрестных запросов (см. Запросы ниже). У меня есть опытный разработчик SQL, но не так много для перекрестного применения, поэтому может быть простое объяснение, которого мне здесь просто не хватает.
Мой вопрос заключается в том, что для этих 2 запросов похоже, что перекрестное применение просто выполняет вызов функции и / или логику для создания столбца, и я мог бы просто сделать это в select и полностью удалить перекрестное применение. Если бы вы могли дать какое-то объяснение, почему я также был бы признателен.
Когда я видел, как используется перекрестное применение, в перекрестном применении всегда было что-то, что по существу соединялось бы с таблицами за пределами перекрестного применения. Что-то вроде этого, например, было бы внутри перекрестного применения для «соединения» таблиц FROM с таблицами в перекрестном применении: soh.SalesOrderID (таблица вне corss) = sod.SalesOrderID (таблица внутри перекрестного)
Я не вижу ничего подобного в приведенных ниже 2 запросах или причины для этого.
SELECT
LeadInventory.LoanNumber,
'Client Age',
PEMWeightByClientAge.PEMWeight,
LeadInventory.ClientAge,
PEMWeightByClientAge.PEMWeight,
#LoanPEMModelHybrid.PEMModel
FROM LeadInventory
INNER JOIN #LoanPEMModelHybrid ON dbo.LeadInventory.LoanNumber = #LoanPEMModelHybrid.LoanNumber
CROSS APPLY
(
SELECT PEMWeight =
CASE
WHEN LeadInventory.ClientAge<=70 AND LeadInventory.ClientAge>=62 Then @PEMWeightAge62To70
WHEN LeadInventory.ClientAge<80 AND LeadInventory.ClientAge>70 THEN @PEMWeightAge71To80
WHEN LeadInventory.ClientAge>=80 THEN @PEMWeightAge80Plus
ELSE 0
END
) AS PEMWeightByClientAge
WHERE #LoanPEMModelHybrid.PEMModel = 'Application'
AND LeadInventory.ClientAge>0
SELECT DISTINCT
IDENTITY(INT, 1,1) AS ID,
LoanNumber,
Calculation.Prob AS TotalPEMScoreForLoan,
PEMModelCode
INTO #PEMScoreHybridFinal
FROM #PEMScoreHybrid
CROSS APPLY
(
SELECT Prob =
CASE PEMModelCode
WHEN 'Initial QQ' THEN CAST (EXP(@INITIALQQBASE TotalPEMScoreForLoan)/(EXP(@INITIALQQBASE TotalPEMScoreForLoan) 1)*100 AS Decimal(9,2))
WHEN 'APPLICATION' THEN CAST (EXP(@APPLICATIONBASE TotalPEMScoreForLoan)/(EXP(@APPLICATIONBASE TotalPEMScoreForLoan) 1)*100 AS Decimal(9,2))
END
) Calculation
Спасибо.
Комментарии:
1. На мой взгляд, вы полностью правы. Это просто неудобный синтаксис. Если бы я писал скрипт, я бы либо превратил его в функцию, либо включил его в инструкцию select. Однако я не уверен, что стал бы утруждать себя его рефакторингом, если он уже работает как есть
Ответ №1:
В первом запросе вы могли бы использовать подзапрос. Однако обратите внимание, что переменная PEMWeightByClientAge.PEMWeight
в CROSS APPLY
используется дважды в SELECT
. Это дает подсказку относительно того, почему была выбрана запись CROSS APPLY
.
Почему вы используете CROSS APPLY
? Существует несколько причин. Самое основное — вызвать функцию, возвращающую набор, для аргументов из таблицы. На самом деле другого способа сделать это нет.
С подзапросом APPLY
является более общим, чем объединения. Это также может улучшить оптимизацию. Если вам не нравится специфика SQL-Сервера APPLY
, просто поймите, что это боковые соединения и они вполне совместимы с другими операциями с базой данных.
У вас есть третий вариант использования. Это позволяет обойти тот факт, что псевдонимы столбцов не могут быть повторно использованы в SELECT
. Подзапросы и CTE являются альтернативами. Недостатком подзапросов является то, что (при правильном отступе) вложенность может оставлять много свободного места слева. CTE являются жизнеспособной альтернативой. То, что кто-то использует, на самом деле является делом вкуса, а не «правильным» или «неправильным».