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

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?

Related

Calculate the difference between the current and the previous row in DAX

In Analysis Services I have a table for Covid Cases, as shown below:
It shows the cumulative cases on a daily basis for 193 different countries. I would like to add a calculated column to calculate the difference between the current row and the previous row, so I can see the daily new cases. Also, as column Country/Region contains 193 different countries, this calculation needs to be somehow grouped for each country. The Date column should also be in the right order.
How should I sort the table and what DAX function should I use to make this work?
Try this
Column =
VAR current =
CALCULATE ( MAX ( tbl[Value] ) )
VAR prev =
MAXX (
FILTER (
tbl,
tbl[Country] = EARLIER ( tbl[Country] )
&& tbl[Date] < EARLIER ( tbl[Date] )
),
tbl[Value]
)
RETURN
current - prev

DAX calculation with date range is performing bad

I have a DAX formula that is performing really bad and hopefully someone here can suggest a solution.
I have a table that contains about 400000 rows of data. ProductID's (example field), startdate, enddate and an IsActive flag field. The data out of this table should be reported in several ways. In some reports I want to see all of the active products within a selected period of time and in other reports, I only want to see the number of products that were active on the last day of the month.
So, I have created two DAX queries to calculate this.
First I calculate the active products:
_Calc_Count Fields :=
CALCULATE (
DISTINCTCOUNT ( MyFactTable[ProductID] ),
FILTER (
MyFactTable,
MyFactTable[StartDate] <= CALCULATE ( MAX ( 'Date'[Date] ) )
&& MyFactTable[EndDate] >= CALCULATE ( MIN ( 'Date'[Date] ) )
),
MyFactTable[IsActive] = 1
)
Please be aware of the fact that the report this calculation is used in can also contain a date range (even a whole year (or multiple years) can be selected with a startdate and enddate selected in the filter). The report also slices on other filters like Client Group.
Then I have a second calculation that uses the first one and applies the LASTNONBLANK function:
Last Non Blank Value :=
CALCULATE (
[_Calc_Count Fields],
LASTNONBLANK ( 'Date'[Date], [_Calc_Count Fields] )
)
Both calculations are very, very slow.
Can anyone suggest a better approach? Can the DAX formula be optimized or should it completely be rewritten?
ps. I am using Analysis Services Tabular Model.
Thank you all in advance for your responses!
there are many points to consider for optimizing.
First of all, you need to understand where is the bottleneck.
I would do three separate preliminary tests:
A) change the DISTINCTCOUNT with a simple COUNT
B) Remove the FILTER
C) Remove the IsActive
Then you can understand where to prioritize your effort, however there are some very simple general optimization you can do anyway:
1.Make use of variables, therefore the formula becomes:
_Calc_Count Fields 3:=
VAR _startdate = CALCULATE ( MAX ( 'Date'[Date] ) )
VAR _enddate = CALCULATE ( MIN ( 'Date'[Date] ) )
RETURN
CALCULATE (
DISTINCTCOUNT ( MyFactTable[ProductID] ),
FILTER (
MyFactTable,
MyFactTable[StartDate] <= _startdate
&& MyFactTable[EndDate] >= _enddate
),
MyFactTable[IsActive] = 1
)
2.If you use as first parameter of FILTER an entire Fact Table, Storage Engine will load in memory the Expanded Table which is very expensive. Therefore, as a second step the formula should become:
_Calc_Count Fields 2:=
VAR _startdate = CALCULATE ( MAX ( 'Date'[Date] ) )
VAR _enddate = CALCULATE ( MIN ( 'Date'[Date] ) )
RETURN
CALCULATE (
DISTINCTCOUNT ( MyFactTable[ProductID] ),
MyFactTable[StartDate] <= _startdate && MyFactTable[EndDate] >= _enddate,
MyFactTable[IsActive] = 1
)
Next, based on the preliminary test you can decide where to invest your effort.
The issue is the DISTINCTCOUNT:
- explore some alternative algorithms for approximating DISTINCTCOUNT (HIGH EFFORT)
- try to sort in the data source (back-end) the table by ProductId to allow better compression in AAS
- make sure ProductId is a Integer Data type with Encoding Hint: Value
The issue is in the FILTER:
- Try to change the "&&" with "," (LOW EFFORT)
- Investigate the cardinality of StartDate and EndDate. If they are DateTime, remove the Time part. (LOW EFFORT)
- Try to change the datasource in the back-end and sort by useful fields (for example, StartDate asc, so when AAS will read the table might perform better compression (LOW EFFORT)
- Make sure StartDate and Date are Whole Number data types, with Encoding Hint: Value (LOW EFFORT)

A way to filter a distinct set of columns using a measure from the same table - Tabular2017

Overview of the table in question
I need to get a distinct count of the column Fkey_Dim_Resource_ID that has holiday to spare.
My Table consists of five columns:
Resource_Allocated_Holiday_ID (Primary Key)
Fkey_Dim_Resource_ID
Fkey_Dim_HolidayYear_ID
Fkey_Dim_Company_ID
Allocated_Holiday_Hrs_Qty
Measure:
Allocated Holiday (Hrs):= Var X= SUM([Allocated_Holiday_Hrs_Qty])
Return if(X =0; BLANK();X)
This measure below then uses the above, and the holiday spent from another metric:
Remaining Holiday (Hrs):= Var X = 'HolidayEntry Numbers'[Allocated Holiday (Hrs)] - [#Holiday Hours]
Return if(X=0;BLANK();X)
And now, I would like a metric that gives me the distinct count of Fkey_Dim_ResourceID where 'Remaining Holiday (hrs)' >0.
I have tried a lot of different stuff, but cannot seem to get it right.
test:=
ADDCOLUMNS(
SUMMARIZE('HolidayEntry Numbers'
;'HolidayEntry Numbers'[Fkey_Dim_Company_ID]
;'HolidayEntry Numbers'[Fkey_Dim_Resource_ID];
'HolidayEntry Numbers'[Fkey_Dim_HolidayYear_Id]
)
;"RemainingHoliday"; sum( [Remaining Holiday (Hrs)])
)
I would like for a distinct count of Fkey_Dim_Resource_ID that has holiday left, that takes into account the context.
Thanks in advance.
With this measure:
test4 virker når ressourcen er med:=COUNTROWS (
FILTER (
ADDCOLUMNS (
VALUES ( 'HolidayEntry
Numbers'[Fkey_Dim_Resource_ID]);
"remholiday"; CALCULATE ( [Remaining Holiday
(Hrs)] )
);
[remholiday] > 0
)
)
I get the following result:
Result of the advice1
So the metric works, when in the context of a Resource, but not when in the context of a Fkey_dim_holiday_Year_ID.
Thanks ion advance.
Resources with remaining holiday hours =
COUNTROWS ( // counts rows in a table
FILTER ( // returns a table, filtering based on predicate
// below is unique values of the column in context, as a
// one-column table
VALUES ( 'HolidayEntry Numbers'[Fkey_Dim_Resource_ID] ),
[Remaining Holiday (hrs)] > 0 // keep rows meeting this criterion
)
)
As a matter of style, you should fully qualify column names as 'Table'[Column], and never fully qualify measure references, i.e. don't prefix with table name. This conforms with all style guides I know, and helps to ensure your code is unambiguous (since both columns and measures are referenced in square brackets).

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.

DAX: Filter on a filter with countrows

I'm working in a dataset (relations) that tracks ownership of firms.
If a firm has 8 owners, the firm has 8 rows in the dataset, one for each owner. A owner can have multiple firms. I want a calculated column that for row shows how many firms the specific owner owns in that sector. It is something like; for each row, search how many times the owner or owners appears in the relationship database but only count those that has the same industry code like the mother firm. This is what i have so far:
=
CALCULATE (
COUNTROWS ( Relations );
FILTER (
Relations;
Relations[participantnumber] = EARLIER ( Relations[participantnumber] )
);
FILTER ( Relations; Relations[127_industry] = Relations[127_industry] )
)
But this just gives me the total amount of firms an owner is mentioned in regardless of industry code.
Thanks!
Try this:
=
CALCULATE (
COUNTROWS ( Relations );
ALLEXCEPT( Relations; Relations[participantnumber]; Relations[127_industry])
)
How it works: for each row, you need to have access to the entire table so that you can count all relevant relations. However, you want to filter the total count by participant and industry that are current for the row. ALLEXCEPT does that - it allows you see the entire table while preserving current participant and industry.

Resources