Tableau Zen Master Ken Flerlage published 20 use cases of Level of Details or LOD a few days ago. I am quite curious as to how different it is to implement them without LOD. So I recreated 19 of 20 examples using simple aggregations or table calculations. Here is the workbook that contains both Ken's original LOD examples and my non-LOD calculations. Hover on the charts to view and compare the formula in LOD and non-LOD.
The main takeaways from these exercises are:
1.In general, LOD and non-LOD are both possible options to implement almost any calculation. One can use either depending on one's mastering of either technique.
2.One can be better than the other depending on use cases.
3.Table calculations can be conceptually more challenging than LOD. LOD is conceptually simpler to understand. Still it depends on one's understanding of either technique.
4.Both options involve similar complexity. Only in some extreme cases with AGG() type of non-linear aggregations, LOD shows greater advantages over non-LOD.
5.When referring to measures derived from dimensions out of view, LOD is more advantageous.
Let us start with all the 20 cases as follows. We mostly explain how to implement the use cases without LOD. In the process, we will compare with LOD implementations and comment on the advantages of one or the other.
1. Deal with Duplicate Records
The easy way to handle this is Avg(Sales).
2. Get a Single Aggregate
The non-LOD solution is TOTAL(MAX([Sales])) computed along Row ID, given one record per row. Otherwise, we should use Window_Max(SUM(Sales)) .
3. Isolate a Specific Value
Use the basic table calculations to compute along Category and Order Date
- WINDOW_MAX(MAX(IF [Category]='Technology' THEN [Order Date] END))
The LOD solution is fairly simple:
Region Month Sales:
- {FIXED [Region], DATETRUNC('month', [Order Date]): SUM([Sales])}
- {FIXED : MAX([Region Month Sales])}
For the non-LOD solution, create first the sales in each of the 4 regions
Sales West: If Region='West' Then Sales End
Max Sales West: WINDOW_MAX(SUM([Sales West])) computing over Order Date.
Same for the other 3 regions.
Find the Max(Sales) among regions ad follows
- MAX(
- MAX([Max Sales East], [Max Sales West]),
- MAX([Max Sales South], [Max Sales Central])
- )
5. Find Min/Max in a Time Series
Use this formula to find sales at min and max:
- IF SUM([Sales]) =WINDOW_MIN(SUM([Sales])) OR
- SUM([Sales]) = WINDOW_MAX(SUM([Sales]))
- THEN
- SUM([Sales])
- END
It is a bit simpler than the LOD solution.
6. Get Related Data
To make the total sum of sales by a particular customer available everywhere, just use the following table calculation:
- TOTAL(SUM(
- IF [Customer Name]=[Selected Customer]
- THEN [Sales]
- END))
- {FIXED : SUM(
- IF [Customer Name]=[Selected Customer]
- THEN [Sales]
- END)}
The non-LOD formula is simple:
- IF [Measure]="Sales" THEN [Value] END
- {FIXED [Region]: SUM(IF [Measure]="Sales" THEN [Value] END)}
8. Get Point-in-Time Data
//Customer Last Order Sales LOD
- IF [Order Date]={FIXED [Customer Name]: MAX([Order Date])}
- THEN [Sales] END
//Customer Last Order Sales (For Comparison) LOD
- {FIXED [Customer Name]: SUM(Customer Last Order Sales )}
//Customer Last Order Sales (No LOD).//Last Date is a set for the Max Order Date.
//Customer Last Order Sales No LOD (Compare)- IF [Last Date] THEN [Sales] END
//Compute along Order ID
- TOTAL(SUM([Customer Last Order Sales No LOD]))
//Quantity Appearances
- {FIXED [Quantity]: SUM([Number of Records])}
- {FIXED : MAX(Quantity Appearances)}
- TOTAL(COUNTD([Row ID]))
- WINDOW_MAX([Quantity Appearances No LOD])
//Date from Set
- {FIXED : MAX(IIF([Date Set],[Order Date],NULL))}
- MAX(IIF([Date Set],[Order Date],NULL))
There are three use cases in this example. LOD presents a very simple solution to the calculation of Grand Total (the 2nd use case). There is no good solution to the problem without LOD.
12. Compare Current & Previous Year
//Difference 2018 to 2019 LOD
- {FIXED MONTH([Order Date]): SUM(IIF(YEAR([Order Date])=2019, [Sales], NULL))}
- -
- {FIXED MONTH([Order Date]): SUM(IIF(YEAR([Order Date])=2018, [Sales], NULL))}
- SUM(IIF(YEAR([Order Date])=2019, [Sales], NULL))
- -
- SUM(IIF(YEAR([Order Date])=2018, [Sales], NULL))
//Orders Above Threshold -Use Dual Axis to label the bar.
- IF {FIXED [Order ID]: SUM([Sales])} > [Order Threshold]
- THEN 1
- ELSE 0
- END
//Created a set for those higher than threshold. Used the set as a filter for the bar.
//Calculate without LOD
- COUNTD([Order ID])
//Month Sales % of Max LOD
- SUM([Sales])/ATTR({FIXED [Sub-Category]:
- MAX({FIXED [Sub-Category], DATETRUNC('month', [Order Date]): SUM([Sales])})})
- SUM([Sales])/WINDOW_MAX(SUM([Sales]))
//National Average Sales LOD
- {FIXED [Country/Region]: AVG([Sales])}
- TOTAL(AVG([Sales]))
//First Purchase Over 10 LOD
- {FIXED [Product Name]: MIN(
- IF [Quantity]>10 THEN [Order Date] END
- )}
- TOTAL(MIN(IF [Quantity>10] THEN [Order Date] END))
// Create Bought One Category and count customers in the category=1
// Dual axis to apply 2 labels
// LOD
- IF {FIXED [Customer Name]: COUNTD([Category])}=1
- THEN 1
- ELSE 0
- END
//Use one label and one reference line for labeling
//No LOD
- CNTD(Customer Name)
//Filter Selection Count (LOD)
- {FIXED : COUNTD([Sub-Category])}
- TOTAL(COUNTD([Sub-Category]))
// Rank the sales by Segment (LOD)
// Sales matches the maximum sales for a segment
- IF SUM([Sales]) = ATTR({FIXED : MAX({FIXED [Segment]: SUM([Sales])})})
- THEN 1
- ELSEIF SUM([Sales]) = ATTR({FIXED : MIN({FIXED [Segment]: SUM([Sales])})})
- THEN 3
- ELSE 2
- END
//Use Quick Table Calculations for Rank
- Sum(Sales)
//Sales Adjusted LOD
- IF ATTR([Sub-Category New]) = "Other" THEN
- MAX([Total Amount]) - SUM([Sales])
- ELSE SUM([Sales])
- END
- {FIXED : SUM([Sales])}/2
- IF ATTR([Sub-Category New]) = "Other"
- THEN SUM([Sales])
- - ZN(TOTAL(SUM(IF [Sub-Category New]!= "Other" THEN [Sales] END)))
- ELSE SUM([Sales])
- END
No comments:
Post a Comment