Коррелированный подзапрос SQL в предложении case - PullRequest
6 голосов
/ 02 июля 2010

возможно ли написать подзапрос в условии case для оператора when

т.

SELECT colA, colB,  
CASE WHEN (SELECT colA FROM tab2 WHERE tab2.colA = tab1.colA) THEN '1'  
CASE WHEN (SELECT colA FROM tab3 WHERE tab3.colA = tab3.colA) THEN '2'  
ELSE '0'  
END AS colC,  
...  
FROM tab1

Расширенный вопрос:
Можно ли что-то сделать, основываясь на этом столбце значений? (уверен, что да, но хотел бы получить подтверждение)
то есть.

CASE  
WHEN colC = '1' THEN ( select colR FROM...),  
WHEN colC = '2' THEN (SELECT ColS FROM...),  
ELSE 'doesn't work'  
END AS colD

Кроме того, разрешено ли в приведенном выше случае возвращать несколько и разные столбцы в зависимости от того, какое значение является colC?
то есть.

CASE  
WHEN colC = '1' THEN ( select colR, colV, colX FROM...),  
WHEN colC = '2' THEN (SELECT ColS, ColD FROM...),  
ELSE 'doesn't work'  
END AS colD

Спасибо!

Ответы [ 3 ]

4 голосов
/ 02 июля 2010

возможно ли написать подзапрос в условии case для оператора when

Я думаю, это то, что вы просите:

SELECT colA, colB,
       CASE 
          WHEN EXISTS (SELECT * FROM tab2 WHERE tab2.colA = tab1.colA) 
             THEN '1'
          WHEN EXISTS (SELECT * FROM tab3 WHERE tab3.colA = tab3.colA) 
             THEN '2'
          ELSE '0'
       END AS colC
  FROM tab1;

Можно ли что-то сделать, основываясь на этом столбце значений?

Вы МОЖЕТЕ сделать это, используя colA вместо colC во втором CASE выражении:

SELECT colA, colB,
       CASE 
          WHEN EXISTS (SELECT * FROM tab2 WHERE tab2.colA = tab1.colA) 
             THEN '1'
          WHEN EXISTS (SELECT * FROM tab3 WHERE tab3.colA = tab3.colA) 
             THEN '2'
          ELSE '0'
       END AS colC, 
       CASE 
          WHEN colA = '1' THEN (SELECT colA FROM tab2)
          WHEN colA = '2' THEN (SELECT colB FROM tab3)
          ELSE 'doesn''t work'
       END AS colD
  FROM tab1;

[Обратите внимание, что вам нужно быть осторожным при приведении результата второго выражения CASE к общему типу данных, предположительно VARCHAR, учитывая значение по умолчанию «не работает».]

Однако, я думаю, вы спрашиваете, можете ли вы «повторно использовать» результат выражения CASE в том же предложении SELECT, в данном случае colC.Ответ на это нет, потому что имя корреляции не входит в область **.Вы, конечно, можете заключить его в подзапрос (или CTE, VIEW и т. Д.):

SELECT DT1.colA, DT1.colB, DT1.colC, 
       CASE 
          WHEN DT1.colC = '1' THEN (SELECT colA FROM tab2)
          WHEN DT1.colC = '2' THEN (SELECT colB FROM tab3)
          ELSE 'doesn''t work'
       END AS colD
  FROM (       
        SELECT colA, colB,
               CASE 
                  WHEN EXISTS (SELECT * FROM tab2 WHERE tab2.colA = tab1.colA) 
                     THEN '1'
                  WHEN EXISTS (SELECT * FROM tab3 WHERE tab3.colA = tab3.colA) 
                     THEN '2'
                  ELSE '0'
               END AS colC
          FROM tab1
       ) AS DT1;

Примечание

** Я скорее основываю свои знания на стандартном SQLчем DB2.Например, MS Access позволяет использовать имена корреляции столбцов в том же предложении SELECT справа налево, но это только подтверждает, что Access не реализует язык SQL!


- в приведенном выше случае разрешено возвращать несколько и разные столбцы в зависимости от того, какое значение colC равно

Разные столбцы да, несколько столбцов нет.Подумайте об этом: выражение CASE возвращает значение, так какой тип данных будет значением двух столбцов?Таблица, список, массив и т. Д.?Скалярные значения являются обязательными для 1NF.

2 голосов
/ 02 июля 2010

Операторы Case оценивают одно значение, поэтому вы не можете вернуть из них несколько столбцов. Вы можете использовать коррелированные подзапросы в предложении Where, хотя вы не показываете пример, где вы пытались это использовать. Будет ли colC работать в предложении Where, будет зависеть от вашего компонента Database Engine. Я работал с некоторыми, которые делают, и с другими, которые требуют, чтобы вы повторно запустили подзапрос в предложении Where.

1 голос
/ 02 июля 2010

возможно ли написать подзапрос в условии case для оператора when

Да. Как ответил g.d.d.c, это должен быть подзапрос, который возвращает одно значение. Это означает ноль или одну строку и один столбец или значение.

Можно ли что-то сделать, основываясь на этом столбце значений?

Да, с теми же оговорками, что и выше.

Кроме того, разрешено ли в приведенном выше случае возвращать несколько и разные столбцы в зависимости от того, какое значение является colC?

Нет. Подзапрос должен возвращать ноль или одну строку и только один столбец или значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...