V službe Oracle Analytics sa príkazy CASE často používajú, keď sa výpočet rozvetvuje na základe hodnoty premennej. Keď sa v príkaze CASE odkazuje na premennú, je lepšie použiť funkciu IndexCol, aby sa zlepšila efektivita vygenerovaného kódu SQL. Táto téma opisuje funkciu IndexCol a kedy ju použiť.
Funkcia IndexCol
Funkcia IndexCol sa používa, keď sa stĺpce alebo hodnoty vo výpočte líšia v závislosti od hodnoty premennej relácie, depozitára alebo prezentácie.
Syntax funkcie IndexCol je::
INDEXCOL(<<integer_literal>>, <<expr_list>>)
Výsledkom prvého argumentu je celé číslo a položky, z ktorých pozostáva argument <<expr_list>>, zodpovedajú počtu možných hodnôt prvého argumentu. Jedna z týchto položiek sa potom použije v príkaze SQL na základe hodnoty prvého argumentu.
Ak má napríklad argument <<integer_literal>> tri možné hodnoty, v argumente <<expr_list>> musia byť tri argumenty, jeden pre každú možnú hodnotu argumentu <<integer_literal>>.
Prvý argument je často založený na hodnote premennej relácie alebo príkazu CASE vo vzťahu k premenným. Funkciu IndexCol môžete modelovať v súbore depozitára (RPD) alebo priamo v stĺpci zostavy. Do jedného príkazu môžete vnoriť viacero funkcií IndexCol.
Výhody funkcie IndexCol
Výpočet používajúci príkaz <<case when>> sa do fyzického kódu SQL vloží ako celok. Na druhej strane, funkcia IndexCol odosiela do databázy iba požadovaný stĺpec alebo výraz. Je to preto, lebo funkcia IndexCol sa vyhodnocuje pred generovaním fyzického kódu SQL.
V kombinácii s výzvami premenných, ktoré umožňujú výber v zozname hodnôt, môžete výrazne upraviť štruktúru zostavy bez akýchkoľvek zvýšených nákladov na výkon.
Jednou nevýhodou funkcie IndexCol je, že ju nemožno používať s operátorom like v celočíselných výpočtoch, aj keď operátor like možno používať v zozname výrazov. Ak celočíselný výpočet vyžaduje operátor like, je potrebné namiesto neho použiť príkaz CASE.
Príklad
Prepokladajme, že existuje premenná relácie s názvom PREFERRED_CURRENCY, ktorá pre používateľa nastaví preferovanú menu. Výnos sa potom na základe hodnoty premennej relácie zobrazí v mene, ktorú zadal používateľ.
Vytvorili sa dva výpočty na vrátenie správnej meny na základe hodnoty premennej relácie.
Prvý používa príkaz CASE takto:
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
ENDDruhý používa funkciu IndexCol takto:
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")Keďže výsledkom prvého argumentu funkcie IndexCol musí byť celé číslo, na získanie tohto výsledku sa používa príkaz CASE.
Keď sa dopyt spustí pomocou výpočtu príkazu CASE, do databázy sa odošle celý príkaz CASE, pretože tento príkaz sa vyhodnocuje v čase behu. V niektorých prípadoch to spôsobuje problémy s optimalizátorom.
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 ) D1Zošity a funkcia IndexCol
Funkciu IndexCol môžete používať v zošitoch.
V tomto príklade sa funkcia IndexCol používa na zmenu granularity obdobia vo vizualizácii:
IndexCol. Tento výpočet je tu:
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")