#sql-server #sql-server-2008 #case #conditional-statements
#sql-сервер #sql-server-2008 #случай #условные операторы
Вопрос:
У меня есть что-то вроде
( COMPLEX_EXPRESSION_N
обозначает длинный подзапрос)
select
ID_Operation,
FirstCheck = CASE WHEN (COMPLEX_EXPRESSION_1)= 0 then 0 else 1 end,
SecondCheck = CASE WHEN (COMPLEX_EXPRESSION_2)= 0 then 0 else 1 end,
ThirdCheck = CASE WHEN (COMPLEX_EXPRESSION_3)= 0 then 0 else 1 end,
AllChecksOk = Case WHEN
(FirstCheck SecondCheck Third CHeck = 3)
Then 'OK' Else 'No' End
from
AllOperationsTable
Можно ли использовать FirstCheck, SecondCheck, ThirdCheck, как я делал в строке AllChecksOk?
Меня не беспокоит производительность, это то, что выполняется вручную один раз в день для очень небольшого количества записей, я просто хочу избежать создания представлений, таблиц или временных таблиц и сохранить все в одном операторе select.
В качестве альтернативы я могу сделать это, но это делает запрос менее читаемым (поскольку мне нужно писать дважды каждое сложное выражение):
select
ID_Operation,
FirstCheck = CASE WHEN (COMPLEX_EXPRESSION_1)= 0 then 0 else 1 end,
SecondCheck = CASE WHEN (COMPLEX_EXPRESSION_2)= 0 then 0 else 1 end,
ThirdCheck = CASE WHEN (COMPLEX_EXPRESSION_3)= 0 then 0 else 1 end,
AllChecksOk = Case WHEN
(COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2
COMPLEX_EXPRESSION_3CHeck = 3) Then 'OK' Else 'No' End
from
AllOperationsTable
Ответ №1:
Вы не можете ссылаться на псевдоним столбца в select
, но вы можете использовать CTE, как показано ниже.
;WITH CTE AS
(
select
ID_Operation,
FirstCheck = CASE WHEN (COMPLEX_EXPRESSION_1)= 0 then 0 else 1 end,
SecondCheck = CASE WHEN (COMPLEX_EXPRESSION_2)= 0 then 0 else 1 end,
ThirdCheck = CASE WHEN (COMPLEX_EXPRESSION_3)= 0 then 0 else 1 end
from
AllOperationsTable
)
SELECT *,
AllChecksOk = Case WHEN
(COMPLEX_EXPRESSION_1 COMPLEX_EXPRESSION_2
COMPLEX_EXPRESSION_3CHeck = 3) Then 'OK' Else 'No' End
FROM CTE
Вы также можете использовать CROSS APPLY
для определения трех псевдонимов столбцов, а затем ссылаться на них в главном SELECT
списке , как в этом примере.
Комментарии:
1. CTE выполнила свою работу, я не искал ПЕРЕКРЕСТНОГО ПРИМЕНЕНИЯ, я добавлю его в закладки на будущее. Спасибо.
Ответ №2:
Ниже представлено производное табличное решение
SELECT
T.ID_Operation,
FirstCheck = CASE WHEN T.Expr1 = 0 THEN 0 ELSE 1 END,
SecondCheck = CASE WHEN T.Expr2 = 0 THEN 0 ELSE 1 END,
ThirdCheck = CASE WHEN T.Expr3 = 0 THEN 0 ELSE 1 END,
AllChecksOk = CASE WHEN T.Expr1 T.Expr2 T.Expr3 = 3 THEN 'OK' ELSE 'No' END
FROM
(
SELECT
ID_Operation,
Expr1 = (COMPLEX_EXPRESSION_1),
Expr2 = (COMPLEX_EXPRESSION_2),
Expr3 = (COMPLEX_EXPRESSION_3)
FROM
AllOperationsTable
) T
Ответ №3:
Лично я нахожу использование CTE или производных таблиц немного запутанным для этой цели, поскольку вам приходится вкладывать вещи на один уровень и думать о последствиях вложенности. Гораздо более простой подход (по крайней мере, на мой взгляд) заключается в использовании APPLY
(или стандартного SQL LATERAL
в других СУБД) для генерации псевдонимов выражений столбцов:
SELECT
ID_Operation,
FirstCheck,
SecondCheck,
ThirdCheck,
AllChecksOk = CASE
WHEN FirstCheck SecondCheck ThirdCheck = 3 THEN 'OK' ELSE 'NO'
END
FROM
AllOperationsTable
CROSS APPLY (
SELECT
FirstCheck = CASE WHEN COMPLEX_EXPRESSION_1 = 0 THEN 0 ELSE 1 END,
SecondCheck = CASE WHEN COMPLEX_EXPRESSION_1 = 0 THEN 0 ELSE 1 END,
ThirdCheck = CASE WHEN COMPLEX_EXPRESSION_1 = 0 THEN 0 ELSE 1 END
) t