Oracle Analitik'te, CASE komutları genellikle bir hesaplama değişken bir değere göre dallara ayrıldığında kullanılır. CASE komutunda bir değişkene referans verildiğinde, oluşturulan SQL kodunun verimliliğini artırmak için bunun yerine IndexCol fonksiyonunun kullanılması tercih edilir. Bu konu IndexCol fonksiyonunu ve ne zaman kullanılacağını açıklar.
IndexCol Fonksiyonu Hakkında
Bir hesaplamadaki sütunlar veya değerler bir oturumun, veri havuzunun veya sunum değişkeninin değerine bağlı olarak değiştiğinde IndexCol fonksiyonunu kullanırsınız.
IndexCol fonksiyonunun söz dizimi::
INDEXCOL(<<integer_literal>>, <<expr_list>>)
İlk bağımsız değişkenin bir tam sayıya çözümlendiği ve <<expr_list>> bağımsız değişkenini oluşturan öğelerin, ilk bağımsız değişkenin olası değerlerinin sayısına karşılık geldiği durumlarda. Bu öğelerden biri daha sonra ilk bağımsız değişkenin değerine göre SQL komutunda kullanılır.
Örneğin <<integer_literal>> bağımsız değişkeninde üç olası değer varsa, <<expr_list>>bağımsız değişkeninde her bir olası <<integer_literal>> değeri için bir adet olmak üzere üç bağımsız değişken olmalıdır.
İlk bağımsız değişken genellikle bir oturum değişkeninin değerini veya değişkenlere ilişkin bir CASE komutunu temel alır. IndexCol fonksiyonunu veri havuzu (RPD) dosyasında veya doğrudan bir rapor sütununda modelleyebilirsiniz. Tek bir komut oluşturmak için birden fazla IndexCol fonksiyonunu iç içe yerleştirebilirsiniz.
IndexCol Fonksiyonunun Avantajları
<<case when>> komutunu kullanan bir hesaplama, fiziksel SQL koduna bütünüyle aktarılır. Bununla karşılaştırıldığında, IndexCol fonksiyonu sadece gerekli sütunu veya ifadeyi veritabanına aktarır. Bunun nedeni, IndexCol fonksiyonunun fiziksel SQL kodu oluşturulmadan önce değerlendirilmesidir.
Değerler listesinden seçim yapılmasına olanak tanıyan değişken bilgi istemleriyle birleştirildiğinde, performansta herhangi bir maliyet artışı olmadan rapor yapısını büyük ölçüde değiştirebilirsiniz.
IndexCol fonksiyonunun bir dezavantajı, tam sayı hesaplamalarında bunu like ile kullanamazsınız, ancak ifade listesinde like kullanabilirsiniz. Bir tam sayı hesaplaması like gerektiriyorsa bunun yerine CASE komutunu kullanmanız gerekir.
Örnek
Bir kullanıcı için tercih edilen para birimini ayarlayan PREFERRED_CURRENCY adlı bir oturum değişkeni olduğunu varsayalım. Daha sonra Gelir, oturum değişkeninin değerine göre kullanıcının belirttiği para biriminde görüntülenir.
Oturum değişkeninin değerine bağlı olarak doğru para birimini döndürmek için iki hesaplama oluşturuldu.
İlki CASE komutunu şöyle kullanıyor:
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İkincisi IndexCol fonksiyonunu şöyle kullanıyor:
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")IndexCol fonksiyonunun ilk bağımsız değişkeninin bir tam sayıya çözümlenmesi gerektiğinden, çözümleme için CASE komutu kullanılır.
CASE komutu hesaplaması kullanılarak bir sorgu çalıştırıldığında, CASE komutu çalıştırma zamanında değerlendirildiğinden CASE komutunun tamamı veritabanına aktarılır. Bazı durumlarda bu optimizer ile ilgili sorunlara neden olur.
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Çalışma Kitapları ve IndexCol
Çalışma kitaplarında IndexCol fonksiyonunu kullanabilirsiniz.
Bu örnekte, bir görselleştirmedeki dönem ayrıntı düzeyini değiştirmek için IndexCol fonksiyonu kullanılmıştır:
IndexCol fonksiyonunu gerçekleştirmek için özel bir hesaplama oluşturun. Hesaplama şu şekildedir:
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")