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")