En Oracle Analytics, las sentencias CASE
se suelen utilizar cuando un cálculo se ramifica según un valor de variable. Cuando se hace referencia a una variable en una sentencia CASE
, es preferible utilizar la función IndexCol
en lugar de mejorar la eficiencia del código SQL generado. En este tema se describe la función IndexCol
y cuándo utilizarla.
Acerca de la función IndexCol
Utilice la función IndexCol
cuando las columnas o los valores de un cálculo varían en función del valor de una variable de sesión, repositorio o presentación.
La sintaxis de la función IndexCol
es:
INDEXCOL(<<integer_literal>>, <<expr_list>>)
Donde el primer argumento se resuelve an un entero y los elementos que componen <<expr_list>>
corresponden al número de valores posibles del primer argumento. Uno de estos elementos se utiliza a continuación en la sentencia SQL según el valor del primer argumento.
Por ejemplo, si el argumento <<integer_literal>>
tiene tres valores posibles, debe haber tres argumentos en el argumento <<expr_list>>
, uno para cada valor posible de <<integer_literal>>.
El primer argumento suele estar basado en el valor de una variable de sesión o una sentencia CASE
en referencia a variables. Puede modelar la función IndexCol
en el archivo de repositorio (RPD) o directamente en una columna de informe. Puede anidar varias funciones IndexCol
para formar una única sentencia.
Ventajas de la función IndexCol
Un cálculo que utilice la sentencia <<case when>>
se envía al código SQL físico en su totalidad. En cambio, la función IndexCol
solo envía la columna o la expresión necesaria a la base de datos. Esto es debido a que la función IndexCol
se evalúa antes de que se genere el código SQL físico.
Cuando se combina con peticiones de datos de variable, que permiten la selección en una lista de valores, puede modificar de forma significativa la estructura del informe sin ningún costo añadido sobre el rendimiento.
Una desventaja de la función IndexCol
es que no se puede utilizar con like
en cálculos de entero, aunque se puede utilizar like
en la lista de expresiones. Si un cálculo de entero requiere un like
, debe utilizar una sentencia CASE
en su lugar.
Ejemplo
Suponga que hay una variable de sesión denominada PREFERRED_CURRENCY
que defina la moneda preferida para un usuario. Además, según el valor de la variable de sesión, , se muestran los ingresos en la moneda especificada por el usuario.
Se han creado dos cálculos para devolver la moneda correcta según el valor de la variable de sesión.
El primero utiliza una sentencia CASE
como se indica a continuación:
CASE WHEN VALUEOF("NQ_SESSION"."PREFERRED_CURRENCY") = 'USD' THEN "01 - Sample App Data (ORCL)".""."BISAMPLE"."F19 Rev. (Converted)"."Revenue_Usd" WHEN VALUEOF("NQ_SESSION"."PREFERRED_CURRENCY") = 'EUR' THEN "01 - Sample App Data (ORCL)".""."BISAMPLE"."F19 Rev. (Converted)"."Revenue_Eur" WHEN VALUEOF("NQ_SESSION"."PREFERRED_CURRENCY") = 'AUD' THEN "01 - Sample App Data (ORCL)".""."BISAMPLE"."F19 Rev. (Converted)"."Revenue_Aud" ELSE NULL END
El segundo utiliza la función IndexCol
como se indica a continuación:
INDEXCOL( CASE VALUEOF("NQ_SESSION"."PREFERRED_CURRENCY") WHEN 'USD' THEN 0 WHEN 'EUR' THEN 1 WHEN 'AUD' THEN 2 END , "01 - Sample App Data (ORCL)".""."BISAMPLE"."F19 Rev. (Converted)"."Revenue_Usd", "01 - Sample App Data (ORCL)".""."BISAMPLE"."F19 Rev. (Converted)"."Revenue_Eur", "01 - Sample App Data (ORCL)".""."BISAMPLE"."F19 Rev. (Converted)"."Revenue_Aud")
Debido a que el primer argumento de la función IndexCol
se debe resolver en un entero, se utiliza una sentencia CASE
para la resolución.
Cuando se ejecuta una consulta utilizando el cálculo de la sentencia CASE
, la sentencia CASE
completa se envía a la base de datos, dado que la sentencia CASE
se evalúa en tiempo de ejecución. En algunos casos, esto genera incidencias con el optimizador.
WITH SAWITH0 AS (select sum(case when 'USD' = 'USD' then T42437.Revenue_Usd when 'EUR' = 'USD' then T42437.Revenue_Eur when 'AUD' = 'USD' then T42437.Revenue_Aud else NULL end ) as c1, T42412.Office_Dsc as c2, T42412.Office_Key as c3 from BISAMPLE.SAMP_OFFICES_D T42412 /* D30 Offices */ , BISAMPLE.SAMP_REVENUE_CURR_F T42437 /* F19 Rev. (Converted) */ where ( T42412.Office_Key = T42437.Office_Key ) group by T42412.Office_Dsc, T42412.Office_Key), SAWITH1 AS (select 0 as c1, D1.c2 as c2, D1.c1 as c3, D1.c3 as c4 from SAWITH0 D1) select D1.c1 as c1, D1.c2 as c2, D1.c3 as c3 from ( select D1.c1 as c1, D1.c2 as c2, D1.c3 as c3 from SAWITH1 D1 order by c2 ) D1 The same query run using the IndexCol function pushes down only the expression needed to satisfy the query, because the IndexCol function is resolved prior to SQL generation. This helps avoid issues with the Optimizer. WITH SAWITH0 AS (select sum(T42437.Revenue_Usd) as c1, T42412.Office_Dsc as c2, T42412.Office_Key as c3 from BISAMPLE.SAMP_OFFICES_D T42412 /* D30 Offices */ , BISAMPLE.SAMP_REVENUE_CURR_F T42437 /* F19 Rev. (Converted) */ where ( T42412.Office_Key = T42437.Office_Key ) group by T42412.Office_Dsc, T42412.Office_Key), SAWITH1 AS (select 0 as c1, D1.c2 as c2, D1.c1 as c3, D1.c3 as c4 from SAWITH0 D1) select D1.c1 as c1, D1.c2 as c2, D1.c3 as c3 from ( select D1.c1 as c1, D1.c2 as c2, D1.c3 as c3 from SAWITH1 D1 order by c2 ) D1
Libros de trabajo e IndexCol
Puede utilizar la función IndexCol
en libros de trabajo.
En este ejemplo, la función IndexCol
se utiliza para cambiar la granularidad del período en una visualización:
IndexCol
. Este cálculo es:
indexcol(case when @parameter("Time Selector Value")('Month')='Month' then 0 else 1 end, "HCM - Workforce Core"."Time"."Month Name", "HCM - Workforce Core"."Time"."Quarter")