Ranking results from a SUMMARIZECOLUMNS operation - dax

I created the following DAX code in DAX Studio which works correctly:
EVALUATE
SUMMARIZECOLUMNS(
'Florida Sightings'[Locality Id],
Hotspot[Subnational 1 Code],
Hotspot[Name],
'Calendar'[Month],
FILTER(Hotspot, Hotspot[Subnational 1 Code] = "US-FL"),
"Species Count", COUNTROWS(VALUES('Florida Sightings'[Common Name]))
)
The output looks like this, sorted by month and species count:
I would like to take the results of the SUMMARIZECOLUMNS and add a rank column based on species count for each locality Id and month. So, for the first locality Id (L127258) and Month (1), the rank would be 1. And, for the second locality Id (L123565) and month (1), the rank would be 2 etc.
The months run from 1 through 12 for each locality.

Without sample data to work with, I'm shooting in the dark a bit but try something along these lines:
ADDCOLUMNS (
SummaryTable,
"Rank", RANKX (
FILTER (
SummaryTable,
[Locality Id] = EARLIER ( 'Florida Sightings'[Locality Id] )
&& [Month] = EARLIER ( 'Calendar'[Month] )
),
[Species Count]
)
)

Related

DAX Query to group column with getting its average of another column where date column is latest one

Let's say I have a table which contains school data with schoolName, StudentCount, Year columns.
What I want is get average of studentCount for latest year by school.
It may possible that school 1 's latest year is 2021 where as school 2 's latest year is 1990.
This is probably late but I guess it can help someone.
The table is named SchoolData and the goal is to average the last record for each school across all schools.
DEFINE
VAR SchoolAndMaxYear = //LastYearForEachSchool
GROUPBY (
SchoolData,
SchoolData[SchoolName],
"YearValue", MAXX ( CURRENTGROUP (), SchoolData[YearValue] )
)
VAR StudentCountForSchoolAndMaxYear =
CALCULATETABLE (
SchoolData,
TREATAS ( SchoolAndMaxYear, SchoolData[SchoolName], SchoolData[YearValue] )
)
EVALUATE StudentCountForSchoolAndMaxYear
EVALUATE
ROW (
"AVGStudentCountLyBySchool", AVERAGEX ( StudentCountForSchoolAndMaxYear, SchoolData[StudentCount] )
)

How to combine 6 tables in one Matrix, show top 12 and categorize the rest as others?

I need to be able to sum availability based on product and say show me top 3, and categorize the rest as Others. I have two tables in a matrix connected by a product table.
I tried so many ways -
i was able to create this measure for July (which is what i will be sorting with) - I get the correct ranking column for July.
i know i'm missing something. i tried to take that ranking measure statement and add an if statement and couldn't get it to do the ranking.
the picture would make more sense *(my formulas are based on actual column names)
Partner Ranking =
VAR summry =
SUMMARIZE (
ALLSELECTED ( Latest ),
[partner_group],
"Sum", COUNT ( Latest[site_url] )
)
VAR tmp =
ADDCOLUMNS ( summry, "RNK", RANKX ( summry, [Sum],, DESC, DENSE ) )
RETURN
MAXX (
FILTER ( tmp, [partner_group] = SELECTEDVALUE ( Latest[partner_group] ) ),
[RNK]
)
I don't know what to do next. how can i do this when i have a separate table that is the product name that links the two tables?

How to write an optimized DAX Measure to aggregate a value by two group by attributes

What if we need to aggregate (Sum) of a value group by two attributes in DAX. I wrote the following measure with Summarize function but it is very slow.
Reorder :=
SUMX (
SUMMARIZE (
TableA,
TableA[ProdID],
TableA[CustID],
"ReordersCount",
VAR VarInvoiceCount =
SUM ( TableA[InvoiceCount] )
RETURN
IF ( VarInvoiceCount > 0, VarInvoiceCount - 1, 0 )
),
[ReordersCount]
)
I also looked for SummarizeColumns but its not working in the report when I am applying other attributes slicers. May be I am missing something?
Looking for optimized solution. Many thanks in advance.
Consider the following approach:
First, create a measure for total number of invoices:
Total Invoice Count = SUM(TableA[InvoiceCount])
Second, create a measure to count a number of first-time invoices, which is simply a number of unique product-customer combinations in your table:
First Invoice Count =
COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
Finally, the desired result is simply the difference of these two measures:
Reorder Count = [Total Invoice Count] - [First Invoice Count]
The formula will respond properly to all slicers and filters, and should be very fast because there are no nested iteration loops such as SUMX(SUMMARIZE()), no context transitions and no call-backs inside the loops caused by using IF statements (that's a bit of an advanced topic).
Of course, you can put everything in one measure using variables:
Reorder Count =
VAR Total_Invoice_Count = SUM(TableA[InvoiceCount])
VAR First_Invoice_Count = COUNTROWS ( SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ) )
VAR Reorder_Count = Total_Invoice_Count - First_Invoice_Count
RETURN Reorder_Count
although personally I prefer to break measures down because individual measures are easier to understand and debug, and they might have their own use.
The above approach is very efficient, but it assumes that TableA contains only valid orders. If it also has cancellations, returns, etc., that might have zero or negative Invoice counts, then you will have to use a less efficient approach, such as:
Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
VAR Reorder_Count = CALCULATE ( SUM ( TableA[Invoice] ) ) - 1
RETURN
IF ( Reorder_Count > 0, Reorder_Count, 0 )
)
or:
Reorder Count =
SUMX (
SUMMARIZE ( TableA, TableA[CustID], TableA[ProdID] ),
MAX(CALCULATE ( SUM ( TableA[Invoice] ) ) - 1, 0) )
Nevertheless, they should be still faster than your original formula.

Filter Dax Calculation based upon YTD Sum

In a Tabular SSAS Model, I'm trying to count the number of distinct customers that purchased a given product wtihin a YTD Timeframe. The table contains measures that aren't explicit sums, so I get the Cartesian Product of all products for each customer, regardless of no sales. I'm attempting to limit the count by filtering out customer / product combinations with YTD Sales = 0. However, I cannot get the FILTER to recognize the DATESYTD context. It only ever filters based upon Sales existing within the chosen calendar month. I've tried inserting the ALL function every which way.
This is what I have so far.
Measure:
CALCULATE (
DISTINCTCOUNT ( Fact[Customer] ),
DATESYTD ( Calendar[Date] ),
FILTER ( Fact,
CALCULATE ( [Sum of Sales], DATESYTD ( Calendar[Date] ) ) <> 0
)
)
This measure will, for example, count distinct customers purchasing a product in Month #5 if Month #5 is explicitly chosen. It will not, however, include a customer that purchased that item in Month #2 of the same year.
I think the following DAX should do the trick:
COUNTROWS(
FILTER(
VALUES(Fact[Customer]),
CALCULATE ( [Sum of Sales], DATESYTD ( Calendar[Date] ) ) <> 0
)
)
Also, make sure your 'Calendar' table has been marked as a date table. If, for some reason, you prefer not to mark it as a date table, rewrite the above DAX to:
COUNTROWS(
FILTER(
VALUES(Fact[Customer]),
CALCULATE ( [Sum of Sales], DATESYTD ( Calendar[Date] ), ALL('Calendar') ) <> 0
)
)
Edit: Do you have records in your fact table where [Sum of Sales] is 0? If not, then you could simplify and improve the performance considerably by writing:
CALCULATE(
DISTINCTCOUNT(Fact[Customer]),
DATESYTD( Calendar[Date] )
)
Again, if you haven't marked your 'Calendar' table as a date table, add ALL(Calendar) to remove the filter on specific calendar columns.

DAX measure with TOTALMTD running slow

I have two measures in my tabular cube.
The first one called
'Number of Days' := CALCULATE(COUNTROWS(SUMMARIZE('A'[Date])))
The second one will includes the first one as its expression
'Number of Days (MTD)' := CALCULATE(TOTALMTD([Number of Days],'A'[Date]))
The second measure when I browse the cube and pull out the measure.
It runs incredibly slow.
Any idea how I can optimize these measurements and make it run faster?
Sample Data
Volume:= SUMX(A, DIVIDE([Volume],2))
Volume (MTD):= TOTALMTD([Volume],'A'[Date])
Updated extra measurements
The best practice should be creating a Calendar/Date table and use TOTALMTD Time Intelligence function. However this approach can be used if your model doesn't include a Date table.
First measure, number of days:
Num of Days := DISTINCTCOUNT(A[Date])
Cumulative measure:
Num of days (MTD) :=
CALCULATE (
[Num of Days],
FILTER (
ALL ( A ),
[Date] <= MAX ( A[Date] )
&& MONTH ( [Date] ) = MONTH ( MAX ( [Date] ) )
&& YEAR ( [Date] ) = YEAR ( MAX ( [Date] ) )
)
)
UPDATE: Added screenshot.
UPDATE 2: It seems you need to calculate a cumulative total, in that case just use the below expression for the second measure:
Num of days (MTD) :=
CALCULATE ( [Num of Days], FILTER ( ALL ( A ), [Date] <= MAX ( A[Date] ) ) )
UPDATE 3: Usuing SUMX and DISTINCT to count distinct dates.
Replace the first measure by the following:
Num of Days = SUMX(DISTINCT(A[Date]), 1)
This solution could be more performant than use COUNTROWS + SUMMARIZE,
however it could be very slow depending on the number of rows and the
machine where it is running.
Let me know if this helps.

Resources