Как использовать значения условных столбцов в том же операторе select?

#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