2010-07-01 18 views
6

es posible escribir una subconsulta dentro de una cláusula de caso para la instrucción whensubconsulta correlacionada SQL en una cláusula de caso

es decir.

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 

pregunta extendida:
¿Es posible hacer algo basado en que la columna de valor? (bastante seguro que sí, pero me gustaría la confirmación)
ie.

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

Además, ¿el caso anterior permite devolver columnas múltiples y diferentes según el valor de colC?
es decir.

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 

¡Gracias!

Respuesta

4

es posible escribir una subconsulta dentro de una cláusula caso de la declaración cuando

Creo que esto es lo que está pidiendo:

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; 

¿Es posible hacer algo basado en en ese valor colum ¿norte?

usted puede hacer esto, que utiliza colA en lugar de colC en la segunda CASE expresión:

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; 

[Nota que tendría que tener cuidado con la fundición del resultado de la segunda CASE expresión a una común tipo de datos, presumiblemente VARCHAR teniendo en cuenta el 'trabajo doesn' valor por defecto.]

Sin embargo, creo que usted está preguntando si se puede 're-uso' el resultado de una expresión CASE en la mismaCláusula, en este caso colC. La respuesta a esto es no, porque el nombre de correlación no está en el alcance **. Se podría, por supuesto, lo envuelve en una subconsulta (o CTE, VIEW, etc):

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; 

Nota

** Estoy basando mis conocimientos en SQL estándar en lugar de DB2. MS Access, por ejemplo, le permite usar nombres de correlación de columnas en la misma cláusula SELECT de derecha a izquierda, pero eso solo confirma que Access no implementa el lenguaje SQL.


es el caso anterior permitió regresar múltiples y diferentes columnas dependiendo de qué valor es colC

Diferentes columnas sí, hay varias columnas. Piénselo: la expresión CASE devuelve un valor, entonces, ¿qué tipo de datos sería un valor de dos columnas? Tabla, lista, matriz, etc. Los valores escalares son un requisito para 1NF.

+0

Gracias por la sugerencia y explicación. – Tyug

2

instrucciones Case evaluar a un solo valor, por lo que no pueden regresar varias columnas de ellos. Puede usar subconsultas correlacionadas en su cláusula Where, aunque no muestra un ejemplo donde intentó usar eso. Si colC funcionará o no en la cláusula Where dependerá de su motor de base de datos. He trabajado con algunos que sí lo tienen y otros que requieren que vuelva a ejecutar la subconsulta en la cláusula Where.

+0

¡Gracias por la explicación! Solo un FYI funciona para DB2. – Tyug

1

es posible escribir una subconsulta dentro de una cláusula para el caso cuando la declaración

Sí. Como g.d.d.c respondió, debe ser una subconsulta que devuelve un único valor. Eso significa cero o una fila y una columna o valor.

¿Es posible hacer algo basado en esa columna de valores?

Sí, con las mismas advertencias que las anteriores.

Además, ¿el caso anterior permite devolver columnas múltiples y diferentes según el valor de colC?

No. La subconsulta debe devolver cero o una fila y solo una columna o valor.

Cuestiones relacionadas