I Oracle Analytics används ofta CASE
-satser när en beräkning förgrenar sig beroende på ett variabelvärde. När en variabel anges i en CASE
-sats bör du använda funktionen IndexCol
i stället för att effektivisera den SQL-kod som genereras. Det här avsnittet beskriver funktionen IndexCol
och när den används.
Om funktionen IndexCol
Du använder funktionen IndexCol
när kolumnerna eller värdena i en beräkning varierar beroende på värdet för en sessionsvariabel, datalagervariabel eller presentationsvariabel.
Funktionen IndexCol
har följande syntax:
INDEXCOL(<<integer_literal>>, <<expr_list>>)
Där det första argumentet tolkas som ett heltal och objekten i <<expr_list>>
är lika många som antalet möjliga värden på det första argumentet. Ett av objekten används sedan i SQL-satsen beroende på det första argumentets värde.
Om argumentet <<integer_literal>>
till exempel har tre möjliga värden måste det finnas tre objekt i argumentet <<expr_list>>
, ett för varje möjligt värde på <<integer_literal>>.
Det första argumentet baseras ofta på värdet av en sessionsvariabel eller en CASE
-sats som refererar till variabler. Du kan modellera funktionen IndexCol
i datalagerfilen (RPD) eller direkt i en rapportkolumn. Du kan kapsla flera IndexCol
-funktioner i en enda sats.
Fördelar med att använda funktionen IndexCol
En beräkning med en <<case when>>
-sats överförs till den fysiska SQL-koden i sin helhet. Som jämförelse överför IndexCol
-funktionen enbart den kolumn eller det uttryck som behövs till databasen. Det beror på att IndexCol
-funktionen utvärderas innan den fysiska SQL-koden genereras.
I kombination med variabelfrågor, där du väljer från en lista med värden, kan du göra stora ändringar i rapportstrukturen utan att få sämre prestanda.
En nackdel med funktionen IndexCol
är att du inte kan använda den med like
i heltalsberäkningar, även om du kan använda like
i listan med uttryck. Om du behöver använda like
i en heltalsberäkning måste du använda en CASE
-sats i stället.
Exempel
Anta att det finns en sessionsvariabel som heter PREFERRED_CURRENCY
som anger en användares önskade valuta. Baserat på sessionsvariabelns värde visas då Intäkt i den valuta användaren har angett.
Två beräkningar har skapats för att returnera korrekt valuta baserat på sessionsvariabelns värde.
I den första används en CASE
-sats, som i det här exemplet:
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
I den andra används funktionen IndexCol
, som i det här exemplet:
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")
Eftersom det första argumentet i IndexCol
-funktionen måste tolkas som ett heltal används ofta en CASE
-sats i tolkningen.
När du kör en fråga med CASE
-satsen överförs hela CASE
-satsen till databasen eftersom CASE
-satsen utvärderas under körningen. Det här kan i vissa fall orsaka problem i optimeringsfunktionen.
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
Arbetsböcker och IndexCol
Du kan använda funktionen IndexCol
i arbetsböcker.
I det här exemplet används IndexCol
-funktionen till att ändra periodens detaljnivå i en visualisering:
IndexCol
. Här är beräkningen:
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")