Oracle

Case en Oracle

Hace algunos días, en mi actual proyecto, me pidieron que revisara una consulta, el problema era que sus tiempos se estaban elevando mucho, y considerando que con el tiempo la tabla iría creciendo aun mas, estamos hablando de millones de registros, era necesario aplicarle un poco de tunning al SQL.

No hablare de cómo optimizar una consulta en este momento, de planes de ejecución, uso de índices o de hints, etc. de lo que quería hablar era de algo mas censillo, del uso del “case” en una consulta.

En versiones anteriores a la 9i (creo que es esa versión la que incluye por primera vez el uso del “case”) no había otra forma de realizar una consulta condicionando el resultado de una columna mas que usando un “decode”, aunque funcionaba, no era una buena solución, no se podían condicionar rangos de valores, para cada valor posible se tenia que definir en el “decode”, resultaba mucho menos claro el código y varias cosas mas en contra.

Al revisar la consulta me doy cuenta que hace un uso extensivo de “decodes”, que aunque funcionan como deben, no es la mejor manera de hacerlo, aparte de que hace el SQL mas difícil de entender y hasta podría decir que también le están afectando a los tiempos de respuesta, no voy a incluir la consulta como tal, mejor dejo unos ejemplos de su uso para aquellos que todavía usan “decodes” en sus consultas.

Supongamos que tenemos una tabla con un campo llamado “TIPO”, los valores para este campo van desde la “A” a la “E”, a la vieja usanza, con un “decode” tendríamos algo así:

1
2
3
4
5
6
SELECT DECODE(TIPO,'A','TIPO A',
                   'B','TIPO B',
                   'C','TIPO C', 
                   'D','TIPO D',
                   'E','TIPO E', 'TIPO NO IDENTIFICADO') TIPO
  FROM TABLA

Ahora modificamos la consulta usando el case:

1
2
3
4
5
6
7
8
9
SELECT CASE TIPO 
          WHEN 'A' THEN 'TIPO A'
          WHEN 'B' THEN 'TIPO B'
          WHEN 'C' THEN 'TIPO C'
          WHEN 'D' THEN 'TIPO D'
          WHEN 'E' THEN 'TIPO E'
          ELSE 'TIPO NO IDENTIFICADO'
       END TIPO
  FROM TABLA

Hasta aquí pues a la vista no varia mucho, las dos las entiendo prácticamente igual, pero este es un ejemplo sencillo, ya verán como se dificultan las cosas cuando hablamos de millones de registros, aparte de que con el “case” ya estas haciendo las cosas como se deben hacer, bien hechas, ahora veamos las ventajas del case, ahora me piden simplemente identificar los valores conocidos y los no conocidos, con un “decode” no se podría tan fácilmente, igual se tendría que usar un “IN” o algo así, pero con el “case” es muy fácil:

1
2
3
4
5
6
SELECT CASE 
          WHEN TIPO BETWEEN 'A' AND 'E' THEN 
             'TIPO IDENTIFICADO'
          ELSE 'TIPO NO IDENTIFICADO'
       END TIPO
  FROM TABLA

Ahora resulta que me piden identificar los valores “A” y “E” para procesarlos de una manera, los valores “B”, “C” y “D” para procesarlos de otra y todos los demás se quedan sin procesar:

1
2
3
4
5
6
7
8
SELECT CASE 
          WHEN TIPO IN ('A','E') THEN 
             'PROCESO A y E'
          WHEN TIPO IN ('B','C','D') THEN 
             'PROCESO B, C y D'
          ELSE 'NO PROCESO'
       END TIPO
  FROM TABLA

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *