How to get DISTINCTCOUNT in GROUPBY table - dax

I have a table 'Report' which contain records of inspection from [StartDate] to [EndDate].
Inspections don't appear every day, so I have [ReportDate] too, but in one day I can have a few inspections.
My table 'Report' has column: A, B, C, StartDate, EndDate, ReportDate.
I want to receive grouping table which will contain number of days when inspection took place.
This number of days should summary DISTINCTCOUNT of [ReportDate].
My problem is that I can not use DISTINCTCOUNT inside of GROUPBY().
So how I can calculate DISTINCTCOUNT?
How to change below DAX statement?
New Table =
GROUPBY('Report'
,'Report'[A]
,'Report'[B]
,"Start Time", MIN ( CURRENTGROUP(), 'Report'[StartDate] )
,"End Time", MAXX ( CURRENTGROUP(), 'Report'[EndDate] )
,"Days", COUNTAX ( CURRENTGROUP(), 'Report'[ReportDate] )
)

Switch to SUMMARIZE:
New Table =
SUMMARIZE(
'Report',
'Report'[A],
'Report'[B],
"Start Time", MIN( 'Report'[StartDate] ),
"End Time", MAX( 'Report'[EndDate] ),
"Days", COUNTA( 'Report'[ReportDate] ),
"Distinct Days", DISTINCTCOUNT( Report[ReportDate] )
)

You directed me to a different solution.
I used twice GROUPBY statement and receive a proper value.
New Table =
GROUPBY(
GROUPBY('Report'
,'Report'[A]
,'Report'[B]
,'Report'[ReportDate]
,"Start Time", MIN ( CURRENTGROUP(), 'Report'[StartDate] )
,"End Time", MAXX ( CURRENTGROUP(), 'Report'[EndDate] )
)
,'Report'[A]
,'Report'[B]
,"Start Time", MIN ( CURRENTGROUP(), [StartDate] )
,"End Time", MAXX ( CURRENTGROUP(), [EndDate] )
,"Days", COUNTAX ( CURRENTGROUP(), [ReportDate] )
)

Related

PowerBi - How to show multiple total columns in Matrix?

I have a slicer from which I can select weeks that I want to show on a matrix. Currently, the matrix only shows the total column at the end of all columns basically summing up all the values.
But I want to show multiple total column (One after each month). Like after the End Of Weeks of one month a total column and so on.
You cannot simply create a Calculated column or Measure to solve this problem. Actually, you can use some logic with Calculated column, but there is a more efficient way. To achieve the goal, you have to create Calculated table based on your date column. You can use that logic to create any custom label for your visuals.
Before we start diving into deep DAX here, let's create a calendar table.
Calendar =
VAR _minSalesDate = CALCULATE( MIN( Sales[Date] ), ALL( Sales ) )
VAR _maxSalesDate = CALCULATE( MAX( Sales[Date] ), ALL( Sales ) )
RETURN
ADDCOLUMNS(
CALENDAR( _minSalesDate, _maxSalesDate ),
"Month", MONTH( [Date] ),
"MonthYear", MONTH( [Date] ) & "-" & YEAR( [Date] )
)
Now, when we have the table with our dates and additional fields, we can start creating a solution for this particular case.
Create a new calculated table as follows:
CustomCategories =
UNION(
SELECTCOLUMNS(
SUMMARIZE(
'Calendar',
'Calendar'[Date],
'Calendar'[Sorter]
),
"Key", 'Calendar'[Date],
"Label", 'Calendar'[Date],
"LabelSorter", 'Calendar'[Sorter]
),
ADDCOLUMNS(
SELECTCOLUMNS(
SUMMARIZE(
'Calendar',
'Calendar'[Date],
'Calendar'[MonthYear],
'Calendar'[Sorter]
),
"Key", 'Calendar'[Date],
"Label", 'Calendar'[MonthYear]
),
"LabelSorter", CALCULATE( MAX( 'Calendar'[Sorter] ), ALLEXCEPT( 'Calendar', 'Calendar'[MonthYear] ) ) + 0.5
),
SELECTCOLUMNS(
ADDCOLUMNS(
SUMMARIZE(
'Calendar',
'Calendar'[Date],
'Calendar'[Sorter]
),
"LabelSorter", CALCULATE( MAX( 'Calendar'[Sorter] ), ALL( 'Calendar' ) ) + 1
),
"Key", 'Calendar'[Date],
"Label", "Total",
"LabelSorter", [LabelSorter]
)
)
Note that the last part of above DAX adding Total is optional.
Once the table has been created, go to the Data view, select CustomCategories table, select Label column and sort the column by LabelSorter (you will find an option on the ribbon). Then go back to your Model view and set a relationship between CustomCategories and your Fact table on Date column.
When you have done with all stuff above, switch back to the Report view. Remove the date column from your table visual and replace it with the newly created Label from CustomCategories table.
Now you should see the desired results.
Hope that helps!
Regards,
Arek

DAX GENERATE & ALLNOBLANKROW functions lead to circular dependency

I'm trying to use a DAX function to generate a table in Power BI. I have a fact table with Opened & Closed date columns and there is a requirement to report at the end of each day/month/year how many items were backlogged.
I've got the table to generate successfully with the code below - essentially joining the date and fact tables, however I can't then link it back to my dimensions due to a circular dependency error.
Researching it online suggests that I need to remove the blank row from fact_task_transaction with the ALLNOBLANKROW function. Unfortunately this has no effect.
Can anyone help?
Backlog Per Day =
var res = SELECTCOLUMNS (
GENERATE (
fact_task_transaction,
FILTER (
ALLNOBLANKROW ( 'Date' ),
AND(
'Date'[Date] >= fact_task_transaction[Opened At Date],
'Date'[Date] <= fact_task_transaction[Closed At Date]
)
)
),
"Date", 'Date'[Date],
"Task ID", fact_task_transaction[Task Id],
"Assignee ID", fact_task_transaction[Assignee Id]
)
return res
try this code - it only uses fact_task_transaction, so the joins with dimensions shuld be working fine
Backlog Per Day =
SELECTCOLUMNS (
GENERATE (
'fact_task_transaction',
GENERATESERIES (
CALCULATE ( MIN ( 'fact_task_transaction'[Opened At Date] ) ),
CALCULATE ( MAX ( 'fact_task_transaction'[Closed At Date] ) ),
1
)
),
"Date", [Value],
"Task ID", fact_task_transaction[Task Id],
"Assignee ID", fact_task_transaction[Assignee Id]
)

DAX low performance when referencing the same measure two times

I designed a set of measures, that in the end should allow me to calculate sales amount w/o cancelled transactions and with discounts
Here are the definitions for those measures:
define measure Sales[Amount] = SUM(Amount)
define measure Sales[Discounted Amount] = CALCULATE(
ABS(SUM(Sales[DiscountValue] ) ),
FILTER(
VALUES( Sales[SalesOrderSource] ),
Sales[SalesOrderSource] = "XXX"
),
USERELATIONSHIP ( Sales, SalesInvoiceDate[SalesInvoiceDate] ),
USERELATIONSHIP ( Sales, SalesOrderDate[SalesOrderDate] ) --
)
define measure Sales[Cancelled Amount] = CALCULATE(
ABS([Amount]),
FILTER( VALUES( 'Sales' ), Sales[Status] = "Cancelled" ),
USERELATIONSHIP ( Sales[InvoiceDate], SalesInvoiceDate[SalesInvoiceDate] ),
USERELATIONSHIP ( Sales[OrderDate], SalesOrderDate[SalesOrderDate] ) --
)
-- RUNNING EXTREMELY SLOW
define measure Sales[AmountNet] = CALCULATE(
[Amount] - [Cancelled Amount] - [Discounted Amount],
USERELATIONSHIP ( Sales[InvoiceDate], SalesInvoiceDate[SalesInvoiceDate] ),
USERELATIONSHIP ( Sales[OrderDate], SalesOrderDate[SalesOrderDate] )
)
Unfortunately, the performance of the final measure Sales[AmountNet] is very slow.
BUT when I remove the [Cancelled Amount] factor from the [AmountNet] definition, it performs well. I suspect it's because of referencing the same measure ([Amount]) two times, where the second reference is overloaded with the FILTER iterator.
I would like to get some support on understanding this behaviour and how this could be rewritten to achieve better performance.
Thanks.
Can you try:
define measure Sales[Cancelled Amount] = CALCULATE(
ABS([Amount]),
KEEPFILTERS( Sales[Status] = "Cancelled" ),
USERELATIONSHIP ( Sales[InvoiceDate], SalesInvoiceDate[SalesInvoiceDate] ),
USERELATIONSHIP ( Sales[OrderDate], SalesOrderDate[SalesOrderDate] ) --
)
My hope is that this approach will be less expensive than FILTER over VALUES(Sales).

Function 'SAMEPERIODLASTYEAR' expects a contiguous selection Issue

I have a tabular data model in Visual Studio, I made a formula to get last year's sales over a given period:
Selected Measure LY:= CALCULATE([Selected Measure], SAMEPERIODLASTYEAR('date' [date]))
I made a formula to have the decomposition of all the months in the 'date' table:
FY_Month='date' [FY Month No]&'date' [Month_label]
And:
FY_Month_No=format(if('date'[month_no]>6,'date'[month_no]-6,'date'[month_no]+6), "00")
Month_label : all the months of the year
The "Selected Measure LY" display works fine when I have all months selected but when I remove one I get this error message:
Calculation error in "Selected Measure LY": the "SAMEPERIODLASTYEAR" function expects a contiguous selection when the date column comes from a tabkle on side 1 of a bidirectional relationship.
Between my 'date' table and my sales table I have a 1/N relationship, I tried to change this relationship too but the error always comes back.
I looked for solutions on forums and I found this but I don't find the same numbers as with my first formula:
Selected Measure LY:=
CALCULATE([Selected Measure],
FILTER (
ALL ( 'date' ),
YEAR ( 'date'[date] ) = YEAR ( TODAY () )
&& 'date'[date] <= TODAY ()
)
)
My code for Selected Measure:
Selected Measure:=
VAR hasFilter =
HASONEFILTER ( 'Measure Selection'[Measure Name] )
VAR selMeas =
SELECTEDVALUE ( 'Measure Selection'[Measure Name], BLANK () ) /*SWITCH works slow, so using many IFs*/
VAR preCalc =
IF (
selMeas = "Units",
[Sku Piece Quantity],
IF (
selMeas = "Net Sales",
[Euro Net Amount],
IF (
selMeas = "Gross Sales",
[Euro Gross Amount],
IF (
selMeas = "Average Wholesale",
[Average_Wholesale],
IF (
selMeas = "Average Units",
[Average Units],
IF (
selMeas = "No of Styles",
[Style Count],
IF (
selMeas = "No of Colours",
[Colour Count],
IF (
selMeas = "ROD by Style",
[ROD by Style],
IF (
selMeas = "Standard Cost",
[Sum_Cost_Base],
IF (
selMeas = "Net Margin",
[Net_Margin],
IF (
selMeas = "Gross Margin",
[Gross_Margin],
IF ( selMeas = "ROD by Colour", [ROD by Colour], BLANK () )
)
)
)
)
)
)
)
)
)
)
)
VAR calc =
IF ( hasFilter, preCalc, BLANK () )
RETURN
calc
How can I correct it?

DAX Default to last value with data

Presently my data returns:
What I need it to do is if the current month has 0's, it will default to the last months value with data:
I know this can be done with nested IF statements, but is there a better way?
UPDATED WITH #TPD SUGGESTION
The results from #TPD suggestion yield:
With measure defined as:
IF([Land Dev Alloc] = 0, CALCULATE([Land Dev Alloc],TOPN(1, CALCULATETABLE(Hyperion,FILTER(ALL(Hyperion), [Land Dev Alloc]>0)),Hyperion[DimDateID],DESC)),[Land Dev Alloc])
Where Hyperion is the main fact table that measure Land Dev Alloc pulls from
I'm not sure if this is the best way but I've recently solved a similar problem like this, assuming you have a Date table and a Value table joined with a relationship:
CurrentOrLastValue:=
CALCULATE (
-- EXTRACT VALUE FROM ROW
FIRSTNONBLANK( 'value'[value], 1 ),
-- FIRST ROW FROM YOUR 'VALUES' TABLE REDUCED TO THOSE BEFORE THE CURRENT CELL DATE
-- ORDERED BY DATE DESC
TOPN (
1,
CALCULATETABLE (
'value',
FILTER
(
ALL( 'date'[date] ),
'date'[date] <= MAX( 'date'[date] )
)
),
'value'[date],
DESC
)
)
Data tables and Pivot Table
Measure
Relationships
UPDATE TO SHOW MEASURE RESULT NOT RAW VALUE
Add a new core measure (doubling values to show a difference):
TotalValue:=SUM('value'[value]) * 2
Add a new measure to show desired output:
CurrentOrLastValueMeasure:=CALCULATE (
[TotalValue],
TOPN(
1,
CALCULATETABLE(
'value',
FILTER(
ALL( 'date'[date] ),
'date'[date] <= MAX( 'date'[date] )
)
),
'value'[date],
DESC
)
)
New measure in pivot table:
UPDATE TO SHOW LAST NON-ZERO VALUE WHEN MEASURE RETURNS ZERO
LastNonZeroMeasure:=
IF( [TotalValue] = 0,
CALCULATE (
[TotalValue],
TOPN(
1,
CALCULATETABLE(
'value',
FILTER(
ALL( 'value' ),
[TotalValue] > 0
)
),
'value'[date],
DESC
)
),
[TotalValue]
)
TotalValue not being doubled anymore. Two data points for 4th Jan to show the measure's aggregation working.
UPDATE TO IGNORE DATES AHEAD OF CELL DATE
Try filtering the dates also...
LastNonZeroMeasure:=IF( [TotalValue] = 0,
CALCULATE (
[TotalValue],
TOPN(
1,
CALCULATETABLE(
'value',
FILTER(
ALL( 'value' ),
[TotalValue] > 0
),
FILTER(
ALL( 'date' ),
'date'[date] < max( 'date'[date] )
)
),
'value'[date],
DESC
)
),
[TotalValue]
)
Ended up being far more simple than originally thought:
MeasureOne BALANCE YTD:= VAR LastNoneblankDate = CALCULATE(max('Date'[DimDateID]),FILTER(ALL('Date'),'Date'[Fiscal_Year] = MAX('Date'[Fiscal_Year])),FILTER(ALL(FactTable),[MeasureOne] > 0)) return IF([MeasureOne]=0, CALCULATE([MeasureOne],FILTER(ALL('Date'),'Date'[DimDateID] = LastNoneblankDate)), [MeasureOne BASE])
Where MeasureOne Base:
MeasureOne BASE:= VAR LastNoneblankDate = CALCULATE(max('Date'[Date]),FILTER(ALL(FactTable),[MeasureOne] > 0)) return IF(HASONEVALUE('Date'[Date]),[MeasureOne], CALCULATE([MeasureOne],FILTER(ALL('Date'),'Date'[Date] = LastNoneblankDate)))
the main issue was setting ALL(FactTable) instead of jut FactTable and handling the cases with

Resources