Introduction
This article is part of a Best Practice series about Oracle Analytics Cloud (OAC) and Oracle Analytics Server (OAS). This article describes ways to improve performance through the use of enhanced formulations of case statements. It’s intended only for technical developers writing formulas for reporting metrics.
Scenarios
You can define case statements in the column formula of reports or in the Oracle Analytics repository (RPD) file.
Case statements defined on variables
This scenario can almost always be rewritten to improve performance. The case logic can be used within an INDEXCOL function, enabling Oracle Analytics to simplify the execution of the case statement so that only the result is queried. INDEXCOL is a conversion function having this syntax: INDEXCOL ([integer literal], [expr1] [, [expr2], ?-]). The first argument must resolve to a number from 0–N, followed by a comma-delimited set of expressions corresponding to the number. Note that a case statement is used to define the integer literal.
Case statement with a presentation variable

Presentation Variable
Original Statement
CASE '@{Metric}{Units}' WHEN 'Revenue'
THEN "Base Facts"."1- Revenue"
WHEN 'Units'
THEN "Base Facts"."2- Billed Quantity"
WHEN 'Paid Amount'
THEN "Base Facts"."4- Paid Amount"
WHEN 'Booked Amount'
THEN "Base Facts"."8- Booked Amount" end
INDEXCOL Version
INDEXCOL (CASE '@{Metric}{Units}' WHEN 'Revenue' THEN 0
WHEN 'Units'
THEN 1
WHEN 'Paid Amount'
THEN 2
WHEN 'Booked Amount'
THEN 3 end,
"Base Facts"."1- Revenue", "Base Facts"."2- Billed Quantity", "Base Facts"."4- Paid Amount", "Base Facts"."8- Booked Amount")
Session Variable
Original Statement
CASE VALUEOF (NQ_SESSION.PREFERRED_CURRENCY) WHEN 'USD' THEN "Base Facts"."83 - Dollars" WHEN 'EURO' THEN "Base Facts"."84 - Euros" WHEN 'YEN' THEN "Base Facts"."85 - Yen" end
INDEXCOL Version
INDEXCOL (CASE VALUEOF (NQ_SESSION.PREFERRED_CURRENCY) WHEN 'USD' THEN 0 WHEN 'EURO' THEN 1 WHEN 'YEN' THEN 2 else 0 end, "Base Facts"."83 - Dollars", "Base Facts"."84 - Euros", "Base Facts"."85 - Yen")
Repository Variable
Original Statement
CASE VALUEOF (REPORTED_CURRENCY) WHEN 'USD' THEN "Base Facts"."83a - Reported Dollars" WHEN 'EURO' THEN "Base Facts"."84a - Reported Euros" WHEN 'YEN' THEN "Base Facts"."85a - Reported Yen" end
INDEXCOL Version
INDEXCOL (CASE VALUEOF (REPORTED_CURRENCY) WHEN 'USD' THEN 0 WHEN 'EURO' THEN 1 WHEN 'YEN' THEN 2 else 0 end, "Base Facts"."83a - Reported Dollars", "Base Facts"."84a - Reported Euros", "Base Facts"."85a - Reported Yen")
Case statements defined on data values
Case statements defined on data values with a single expression
This scenario is complex and can vary for each row returned from the query. The FILTER function replaces the case statement in this scenario. The FILTER function computes an aggregate expression with the given pre-aggregate filter. The syntax is: FILTER (measure USING filter expression).
Original Statement
CASE WHEN "Orders"."R1 Order Status" in ('1-Booked', '2-Fulfilled', '3-Shipped') and "Orders"."R2 Order Type" = 'Express'
THEN "Base Facts"."1- Revenue" else 0 END
FILTER Version
IFNULL (
FILTER ("Base Facts"."1- Revenue"
using "Orders"."R1 Order Status" in ('1-Booked', '2-Fulfilled', '3-Shipped') and "Orders"."R2 Order Type" = 'Express'), 0)
Case Statements defined on data values for multiple expressions
This scenario is the most complex, because multiple FILTER functions must be added to get the desired results.
Original Statement
CASE WHEN "Orders"."R1 Order Status" in ('1-Booked', '2-Fulfilled', '3-Shipped') and "Orders"."R2 Order Type" = 'Express'
THEN "Base Facts"."1- Revenue" WHEN "Orders"."R1 Order Status" in ('6-Cancelled', '9-On Hold')
THEN "Base Facts"."2- Billed Quantity" WHEN "Orders"."R2 Order Type"='Secure' THEN "Base Facts"."7- Shipped Amount" ELSE 0 END
Equivalent Version Using Filters
IFNULL (FILTER ("Base Facts"."1- Revenue"
using "Orders"."R1 Order Status" in ('1-Booked', '2-Fulfilled', '3-Shipped') and "Orders"."R2 Order Type" = 'Express'), 0)
+ IFNULL (FILTER ("Base Facts"."2- Billed Quantity"
using ("Orders"."R1 Order Status" in ('1-Booked', '2-Fulfilled', '3-Shipped') and "Orders"."R2 Order Type" <> 'Express') or "Orders"."R1 Order Status" in ('6-Cancelled', '9-On Hold', '2-Fulfilled')), 0)
+ IFNULL (FILTER ("Base Facts"."7- Shipped Amount" using
"Orders"."R2 Order Type" = 'Secure' and "Orders"."R1 Order Status" not in ('6-Cancelled', '9-On Hold', '2-Fulfilled')), 0)
Call to action
To ensure your report formulas result in the best performance, review how case statements are used and consider: replacing case statements with the INDEXCOL function, which improves query performance; and replacing case statements with FILTER functions, which often improves query performance, but not always.
Use these methods to find reports using case functions:
- Use Catalog Manager and search for CASE in catalog objects.
- Use usage tracking and search for CASE in reports and queries.
For additional information on usage tracking, check here for OAC; here for OAS; and here for Catalog Manager.
To learn more about Oracle Analytics, visit oracle.com/analytics, follow us on twitter@OracleAnalytics, and connect with us on LinkedIn.
