oracle: декодирование и выбор подзапроса - PullRequest
7 голосов
/ 01 июня 2011

У меня есть запрос оракула, и часть его вычисляет некоторое значение, используя DECODE.Например:

SELECT ..., 
      (SELECT DECODE((SELECT 23 FROM DUAL), 
                      0, null,
                     (SELECT 23 FROM DUAL))  
         FROM DUAL) 
  FROM ...

Здесь значение "23" вычисляется во время выполнения, и это довольно сложные объединения - несколько таблиц, используется PARTITION BY и т. Д. Поэтому я хочу избежать выполнения одного и того же подзапроса, если значениене "0".Есть ли способ написать что-то вроде этого

SELECT ..., 
       (SELECT DECODE ((SELECT 23 FROM DUAL) as test, 
                        0, null,
                       test)  
         FROM DUAL) 
  FROM ...

Ответы [ 5 ]

10 голосов
/ 01 июня 2011

Будет ли это работать для вас?Я только что переместил «23» во встроенную таблицу с описательным псевдонимом.

select ..., 
  (
   select 
     decode ( 
            computed_value.val, 
            0, null,
            computed_value.val
            )  
   from
     (select 23 as val from dual) computed_value
  )
from
  ...

Инструкция CASE также может добавить ясности, как в:

select
  ...
 ,case when computed_value.val = 0
       then null
       else computed_value.val
       end as my_field
from
  (select 23 as val from dual) computed_value
  ...
1 голос
/ 01 июня 2011

Для этого конкретного сценария вы можете использовать функцию NULLIF:

SELECT ..., 
      (SELECT NULLIF((SELECT 23 FROM DUAL), 0)  
         FROM DUAL) 
  FROM ...

Функция NULLIF возвращает NULL, если два аргумента равны, в противном случаевозвращает первый аргумент.

1 голос
/ 01 июня 2011

Или:

WITH q AS (
SELECT 23 test, 16 test2 FROM dual
)
SELECT ... 
     , DECODE(q.test, 0, NULL, q.test) value
     , CASE WHEN q.test2 = 0 THEN NULL 
            WHEN q.test2 = 16 THEN 1
            ELSE q.test2
       END another_value
  FROM q, ...

Позволяет использовать запрос "q" во всем основном выборе, где разрешен подзапрос.Вызывается предложение WITH, или выражение общей таблицы, или факторинг подзапроса.Узнайте больше об этом на Oracle-Base.com .

0 голосов
/ 27 июля 2012

Лучше бы вы использовали оператор CASE.поскольку оператор CASE похож на серию операторов IF, он использует только ключевое слово WHEN.Оператор CASE оценивается сверху вниз.Если условие истинно, то выполняется соответствующее предложение THEN, и выполнение переходит к предложению END CASE (оценка короткого замыкания).

0 голосов
/ 01 июня 2011

Вы можете использовать подзапрос в предложении from и сделать что-то вроде ниже:

select conf_key, decode(test, 0, null, test) from (
select conf_key, (select conf_value from config_values where conf_key = 'DOMAINID') as TEST from config_values )
...