2011-06-01 15 views
7

Tengo una consulta de Oracle y parte de ella está calculando algún valor con DECODE. Por ejemplo:oráculo: decodificar y subconsulta seleccionar resultado

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

Aquí el valor "23" se calcula en tiempo de ejecución, y es bastante complicado une - varias tablas, utiliza PARTITION BY etc Así que quiero evitar la ejecución de la misma subconsulta si el valor no es "0 ". ¿Hay alguna manera de escribir algo como esto?

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

Respuesta

9

¿Te sirve esto? Acabo de mover el "23" a una tabla en línea con un alias descriptivo.

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

Una declaración de caso también podría añadir claridad, como en:

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 
    ... 
+0

gracias por su entrada simple y útil. – hanumant

0

Puede utilizar la sub consulta en la cláusula from y hacer algo, como a continuación:

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) 
1

O:

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, ... 

Permite utilizar la consulta "q" thro a través de su selección principal, siempre que se permita una subconsulta. Llamada la cláusula WITH, o Common Table Expression, o Subquery Factoring. Obtenga más información al respecto en Oracle-Base.com.

+0

Hola @DCookie, gracias por su aporte. No puedo usar 'con' ya que la subconsulta usa algunos valores de la consulta externa. – hanumant

1

Para este escenario en particular, se puede usar la función NULLIF:

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

La función devuelve NULLIFNULL si los dos argumentos son iguales, de lo contrario, devuelve el primer argumento.

0

Será mejor que haya usado la instrucción CASE. ya que la sentencia CASE es como una serie de declaraciones IF, solo usando la palabra clave WHEN. Una declaración CASE se evalúa de arriba a abajo. Si una condición es verdadera, se ejecuta la correspondiente cláusula THEN y la ejecución salta a la cláusula END CASE (evaluación de cortocircuito).

Cuestiones relacionadas