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 konuda, IndexCol
fonksiyonu ve ne zaman kullanılacağı açıklanır.
IndexCol Fonksiyonu
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 tamsayı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.
Fonksiyonun 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ı, tamsayı hesaplamalarında bunu "like" ile kullanamazsınız, ancak ifade listesinde "like" kullanabilirsiniz. Bir tamsayı hesaplaması "like" gerektiriyorsa bunun yerine Case komutunu kullanmanız gerekir.
Örnek:
Bir kullanıcı için tercih edilen para birimini ayarlayan PREFERRED_CURRENCY
adında bir oturum değişkeni olduğunu ve ardından oturum değişkeninin değerine bağlı olarak Gelirin kullanıcı tarafından belirtilen para biriminde görüntülendiğini varsayalım.
Oturum değişkeninin değerine bağlı olarak doğru para birimini döndürmek için iki hesaplama oluşturuldu.
İlki bu örnekte olduğu gibi bir Case komutunu 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 bu örnekte olduğu gibi IndexCol
fonksiyonunu kullanır.
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 tamsayı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
Parametrelerin gelmesiyle birlikte IndexCol
fonksiyonu artık çalışma kitaplarında kullanılabilir.
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")