ใน Oracle Analytics ระบบมักใช้คำสั่ง CASE
เมื่อการคำนวณ "branches" เป็นไปตามค่าตัวแปร เมื่อมีการอ้างอิงตัวแปรในคำสั่ง CASE
ควรใช้ฟังก์ชัน IndexCol
แทนเพื่อปรับปรุงประสิทธิภาพของรหัส SQL ที่สร้าง หัวข้อนี้จะอธิบายเกี่ยวกับฟังก์ชัน IndexCol
และเวลาที่ควรใช้
ข้อมูลเกี่ยวกับฟังก์ชัน IndexCol
คุณใช้ฟังก์ชัน IndexCol
เมื่อคอลัมน์หรือค่าในการคำนวณแตกต่างกันไป ขึ้นอยู่กับค่าของเซสชัน พื้นที่เก็บข้อมูล หรือตัวแปรการนำเสนอ
รูปแบบคำสั่งของฟังก์ชัน IndexCol
คือ:
INDEXCOL(<<integer_literal>>, <<expr_list>>)
ตำแหน่งที่อาร์กิวเมนต์แรกแปลค่าเป็นจำนวนเต็ม และรายการที่ประกอบด้วย <<expr_list>>
สอดคล้องกับจำนวนค่าที่เป็นไปได้ของอาร์กิวเมนต์แรก ซึ่งจากนั้นระบบจะใช้หนึ่งในรายการเหล่านี้ในคำสั่ง SQL ตามค่าของอาร์กิวเมนต์แรก
ตัวอย่างเช่น หากอาร์กิวเมนต์ <<integer_literal>>
มีค่าที่เป็นไปได้สามค่า ก็จะต้องมีสามอาร์กิวเมนต์ในอาร์กิวเมนต์ <<expr_list>>
ก็คือหนึ่งอาร์กิวเมนต์สำหรับค่าที่เป็นไปได้แต่ละค่าของ <<integer_literal>>
อาร์กิวเมนต์แรกสุดมักเป็นไปตามค่าของตัวแปรเซสชัน หรือคำสั่ง CASE
ในการอ้างอิงถึงตัวแปร คุณสามารถกำหนดโมเดลฟังก์ชัน IndexCol
ในไฟล์พื้นที่เก็บข้อมูล (RPD) หรือในคอลัมน์รายงานได้โดยตรง คุณสามารถซ้อนฟังก์ชัน IndexCol
หลายฟังก์ชันเพื่อสร้างคำสั่งเดียวได้
ประโยชน์ของฟังก์ชัน IndexCol
การคำนวณโดยใช้คำสั่ง <<case when>>
จะถูกพุชไปยังรหัส SQL แบบฟิสิคัลอย่างครบถ้วน จากการเปรียบเทียบ ฟังก์ชัน IndexCol
จะส่งต่อเฉพาะคอลัมน์หรือเอ็กซ์เพรสชันที่จำเป็นไปยังฐานข้อมูล นี่เป็นเพราะมีการประมวลผลฟังก์ชัน IndexCol
ก่อนที่จะสร้างรหัส SQL แบบฟิสิคัล
เมื่อรวมกับพรอมต์ของตัวแปร ซึ่งอนุญาตให้เลือกลิสต์ค่า คุณสามารถแก้ไขโครงสร้างรายงานได้มากมายโดยไม่มีค่าใช้จ่ายด้านประสิทธิภาพเพิ่มเติม
ข้อเสียประการหนึ่งของฟังก์ชัน IndexCol
คือ คุณไม่สามารถใช้ฟังก์ชันกับ like
ในการคำนวณจำนวนเต็ม แม้ว่าคุณจะสามารถใช้ like
ในลิสต์ของเอ็กซ์เพรสชันได้ก็ตาม หากการคำนวณจำนวนเต็มต้องมี like
คุณต้องใช้คำสั่ง CASE
แทน
ตัวอย่าง
สมมติว่ามีตัวแปรเซสชันชื่อ PREFERRED_CURRENCY
ที่กำหนดสกุลเงินที่ต้องการสำหรับผู้ใช้ จากนั้น ตามค่าของตัวแปรเซสชัน รายได้จะแสดงในสกุลเงินที่ผู้ใช้ระบุ
มีการสร้างการคำนวณสองรายการเพื่อแสดงสกุลเงินที่ถูกต้องตามค่าของตัวแปรเซสชัน
การคำนวณรายการแรกใช้คำสั่ง CASE
ตามที่แสดงดังนี้
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
การคำนวณรายการที่สองใช้ฟังก์ชัน IndexCol
ตามที่แสดงดังนี้
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
ต้องแปลค่าเป็นจำนวนเต็ม ระบบจะใช้คำสั่ง CASE
สำหรับการแปลค่า
เมื่อรันการสืบค้นโดยใช้การคำนวณคำสั่ง CASE
ระบบจะส่งต่อคำสั่ง CASE
ที่ครบถ้วนไปยังฐานข้อมูล เนื่องจากมีการประมวลผลคำสั่ง CASE
ขณะรันไทม์ ในบางกรณี กระบวนการนี้จะทำให้เกิดปัญหากับออปติไมเซอร์
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
เวิร์กบุคและ IndexCol
คุณสามารถใช้ฟังก์ชัน IndexCol
ในเวิร์กบุค
ในตัวอย่างนี้ ระบบใช้ฟังก์ชัน IndexCol
เพื่อเปลี่ยนความละเอียดของระยะเวลาในการแสดงข้อมูล
IndexCol
การคำนวณมีรูปแบบดังนี้
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")