DAX subquery measure? - powerbi

I'm struggling with a DAX query and wondered if you could help?
Consider this table (or visualisation) called 'Builds':
Build....App....Status
Build1...App1...UAT
Build1...App2...Complete
Build2...App1...Complete
Build2...App2...Complete
I would like to add a measure column called 'AppsOutstanding' to show a count of Apps for that Build that aren't 'Complete'. Like so:
Build....App....Status......AppsOutstanding
Build1...App1...UAT.........1
Build1...App2...Complete....1
Build2...App1...Complete....0
Build2...App2...Complete....0
I almost need to do a 'subquery' measure!? Something like:
SELECT COUNT(Status) FROM Builds
WHERE Build = [The Build In This Row]
AND Status <> 'Complete'
I'm a bit stumped how to translate this into DAX? Here is my unsuccessful attempt:
AppsUnavailable = CALCULATE (
count(Builds[Build]),
CALCULATETABLE (
SUMMARIZE ( Builds,Builds[Status] ),
Builds[Status] <> "Complete"
))
Thanks in advance!
UPDATE
I've tried this, but the count isn't working, and also this DAX filters "Complete" statuses out of my actual results! Which i don't want. I only want to filter the "Complete" statuses out of my count measure....
AppsUnavailable =
CALCULATE (
COUNT ( Builds[Build] ),
FILTER (
ALL ( Builds[Build] ),
Builds[Build] = SELECTEDVALUE ( Builds[Build] )
),
FILTER (
ALL ( Builds[Status] ),
Builds[Status] <> "Complete"
)
)
UPDATE 2
I think I'm doing something fundamentally wrong. I've really dumbed it down to just find other 'Builds' with the same name, and it still only returns 1's!
AppsUnavailable =
CALCULATE (
COUNT ( Builds[Build] ),
FILTER (
ALL ( Builds[Build] ),
Builds[Build] = SELECTEDVALUE ( Builds[Build] )
)
)
UPDATE 3
This query (when testing on a single table (no joins) sample) produces this:
Build....App....Status......AppsOutstanding
Build1...App1...UAT.........1
Build1...App2...Complete....0
Build1...App2...UAT.........1
Build2...App1...Complete....0
Build2...App2...Complete....0
But i actually need this:
Build....App....Status......AppsOutstanding
Build1...App1...UAT.........2
Build1...App2...Complete....0
Build1...App2...UAT.........2
Build2...App1...Complete....0
Build2...App2...Complete....0
So Build1 has 2 Apps that are not complete.
I then need to look into why I'm getting all 1's in the 'live' environment. It must be to do with filtering on 2 tables as opposed to 1....

You can replace [The Build In This Row] with SELECTEDVALUE ( Builds[Build] ).
Try this:
AppsUnavailable =
CALCULATE (
COUNT ( Builds[App] ),
FILTER (
ALL ( Builds[Status], Builds[Build] ),
Builds[Build] = SELECTEDVALUE ( Builds[Build] )
&& Builds[Status] <> "Complete"
)
) + 0
powerBI Table visualization internal use SUMMARIZECOLUMNS which is removed row without data from the measure. You have 2 options:
-Right click on GroupBy Column -> "Show item with no data"
-Add +0 to calculation after the last parenthesis
UPDATE:
CALCULATE (
COUNT ( YourTable[App] ),
FILTER (
ALL ( YourTable[App], YourTable[Build], YourTable[Status] ),
YourTable[Build] = SELECTEDVALUE ( YourTable[Build] )
&& YourTable[Status] <> "Complete"
)
) + 0

Related

How to calculate headcount in PowerBI

I have some problem with the HR Dashboard, where I can't get it to work properly.
I have the following visuals:
Visual for HR Dashboard
The headcount code is as follow:
Headcount = CALCULATE (
DISTINCTCOUNT ( FactTable[EmpID]),
FILTER ( ALL(FactTable), FactTable[EmploymentStatus] = "Active" )
)
The problem is, that the visual doesn't slice on the seniority.
Need help.
I have try with some sample data, i guess the issue here is due to you are using filter function, you can try my method if the problem can be solved:
1)I have this original sample table
I have created a measure to count the total employee still with company
Total count = CALCULATE(COUNT(Sheet1[ID]),Sheet1[Status] = "active")
3)My scorecard has displayed the total count correct for with junior slicer
First its bad maner to write code like this:
CALCULATE (
DISTINCTCOUNT ( FactTable[EmpID] ),
FILTER (
ALL ( FactTable ),
AND (
FactTable[DateofHire] <= MIN ( 'Kaldt funktion'[Date] ),
OR (
FactTable[DateofTermination] = BLANK (),
FactTable[DateofTermination] >= MAX ( 'Kaldt funktion'[Date] )
)
)
)
)
A good practice is to use ALL with columns that you really need in your filter. Second instead of comparing column = BLANK() use function ISBLANK(Table[ColumnName]). You also should compare SELECTEDVALUE to get the correct data. (unfortunately, you don't post any samples, and I don't know how your data looks like I can only guess). How is correlated 'Kaldt funktion' with FactTable? Probably problem is in your MIN and MAX. We can also use && insted of AND, and || insted of OR;
CALCULATE (
DISTINCTCOUNT ( FactTable[EmpID] ),
FILTER (
ALL ( FactTable[DateofHire], FactTable[DateofTermination] ),
SELECTEDVALUE ( FactTable[DateofHire] ) <= MIN ( 'Kaldt funktion'[Date] )
&& (
ISBLANK ( FactTable[DateofTermination] )
|| SELECTEDVALUE ( FactTable[DateofTermination] ) >= MAX ( 'Kaldt funktion'[Date] )
)
)
)

DAX - Find and return the category value with the highest summarized measure

In the following example,
Highest Shipping Unit - should be the "ActualArea" where TotalPS has the maximum value.
This is a summarized table grouped by - Customer_ID, ProductDesignation,Package_CD,ActualArea
As you can see above I cannot produce the desired results. The DAX for HighestShippingUnit measure is as follows. I can't seem to figure out what I'm doing wrong.
HighestShippingUnit =
VAR tab =
SUMMARIZE (
ALLEXCEPT (
DeviationReport,
DeviationReport[CUSTOMER_ID],
DeviationReport[ProductDesignation],
DeviationReport[PACKAGE_CD]
),
DeviationReport[ActualArea],
"GroupTotalPS", SUM ( DeviationReport[TotalPS] )
)
VAR maxps =
MAXX ( tab, [GroupTotalPS] )
RETURN
CALCULATE (
MAXX ( FILTER ( tab, [GroupTotalPS] = maxps ), MAX ( [ActualArea] ) )
)
DeviationReport is the name of my table in the dataset.
Please can you tell me what I'm doing wrong in my DAX or how to do it in a more efficient manner?
You were actually very close with your attempt.
If you change the final line from
CALCULATE (
MAXX ( FILTER ( tab, [GroupTotalPS] = maxps ), MAX ( [ActualArea] ) )
)
to
MAXX ( FILTER ( tab, [GroupTotalPS] = maxps ), [ActualArea] )
then it should work.
The reason is that using CALCULATE re-introduces the ActualArea filter context that you removed with ALLEXCEPT so that you only see the current ActualArea.
Thanks to #Alexis Olson. I managed to fix the problem.
The DAX is as follows -
HighestShippingUnit =
VAR tab =
SUMMARIZE (
ALLEXCEPT (
DeviationReport,
DeviationReport[CUSTOMER_ID],
DeviationReport[ProductDesignation],
DeviationReport[PACKAGE_CD]
),
DeviationReport[CUSTOMER_ID],
DeviationReport[ProductDesignation],
DeviationReport[PACKAGE_CD],
DeviationReport[ActualArea],
"GroupTotalPS", SUM ( DeviationReport[TotalPS] )
)
RETURN
MAXX(TOPN(1, tab, [GroupTotalPS]), [ActualArea])
)

Is there a way to dynamically switch which relationship is active in powerpivot (based on slicer selection)?

I have a fact table (MORT) and a dimension table (GEO) in PowerPivot (2016). There are two joins between the tables with two columns in MORT relating to one column in GEO. We can call one join RES and the other REG. I have a large number of measures and I want to allow the user to quickly change between seeing the measures using the RES and REG relationships - essentially I want to be able to switch the active relationship (referred to as switch in the code). This would probably be based on a detached slicer.
I have tried nesting an if statement and various ways of defining a variable to use in a CALCUATE but either have the error that USERELATIONSHIP can only be used in a calculate (in the case of the if) or that USERELATIONSHIP only accepts a column reference (in the case of the var).
IF STATEMENT
MEASURE:= CALCULATE(COUNT(MORT[ID]), GEO,
IF(LASTNONBLANK(SWITCH,1)="RES",
USERELATIONSHIP(MORT[RES], GEO[AREA]),
USERELATIONSHIP(MORT[REG], GEO[AREA]))
VAR
MEASURE:=
VAR switch = IF(LASTNONBLANK(Switch,1)="RES", MORT[RES], MORT[REG])
RETURN
CALCULATE(COUNT(MORT[ID]), GEO, USERELATIONSHIP(switch, GEO[AREA])
I could create every measure with an if statement at the start to check the value of switch but this creates a lot of duplicate code.
I want some way for the end user to change the active relationship in a measure but ideally without a lot of duplicated code.
How about like this?
MEASURE :=
IF (
LASTNONBLANK ( Switch, 1 ) = "RES",
CALCULATE ( COUNT ( MORT[ID] ), GEO, USERELATIONSHIP ( MORT[RES], GEO[AREA] ) ),
CALCULATE ( COUNT ( MORT[ID] ), GEO, USERELATIONSHIP ( MORT[REG], GEO[AREA] ) )
)
Edit:
In your comment, you said you tried this:
M :=
VAR calc =
FILTER ( MORT, MORT[CAUSE] >= "I" && 'Remake Data'[CAUSE] <= "I9" )
VAR select =
IF (
HASONEVALUE ( 'SWITCH'[Switch] ),
LASTNONBLANK ( 'SWITCH'[Switch], 1 ),
"ERROR"
)
RETURN
IF (
select = "RES",
CALCULATE ( COUNTROWS ( calc ), USERELATIONSHIP ( MORT[RES], GEO[Area] ) ),
IF (
selection = "REG",
CALCULATE ( COUNTROWS ( calc ), USERELATIONSHIP ( MORT[REG], GEO[Area] ) ),
"ERROR"
)
)
There are a few problems with this, but mainly, if you define something as a variable, then it's constant and won't be affected by other things within a CALCULATE. Try the following instead.
Define a new measure:
CountRowsMeasure =
COUNTROWS ( FILTER ( MORT, MORT[CAUSE] >= "I" && 'Remake Data'[CAUSE] <= "I9" ) )
Then use that measure within your M measure:
M =
VAR select = SELECTEDVALUE( 'SWITCH'[Switch], "ERROR" )
RETURN
SWITCH (
select,
"RES", CALCULATE ( [CountRowsMeasure], USERELATIONSHIP ( MORT[RES], GEO[Area] ) ),
"REG", CALCULATE ( [CountRowsMeasure], USERELATIONSHIP ( MORT[REG], GEO[Area] ) ),
"ERROR"
)

How do I calculate the sum of Value for the last 6 sprints using DAX

Problem:
I need a calculated measure in DAX that sums the Value column for the last 6 sprints. I am basing the last 6 sprints on the DimSprintEndDateKey in descending order.
Table structure in PowerBI
The DAX that I am using:
CALCULATE (
SUM ( factSprint[Value] ),
FILTER (
ALL ( factSprint ),
COUNTROWS (
topn(6,
FILTER (
factSprint,
EARLIEST( RELATED ( dimSprint[DimSprintEndDateKey] ) )
> RELATED ( dimSprint[DimSprintEndDateKey] )
),RELATED ( dimSprint[DimSprintEndDateKey] ), DESC
)
)
)
)
I am assuming that the relationship on your tables is between 'dimSprint'[dimSprintKey] and 'FactSprint'[dimSprintKey].
That being the case, this measure could work for you.
Total Value Last Six Sprints =
VAR endDateSprint =
LOOKUPVALUE (
'dimSprint'[dimSprintEndDateKey],
'dimSprint'[dimSprintKey], SELECTEDVALUE ( 'FactSprint'[dimSprintKey] )
)
VAR dimTableFiltered =
FILTER ( 'dimSprint', 'dimSprint'[dimSprintEndDateKey] <= endDateSprint )
RETURN
CALCULATE (
SUM ( 'FactSprint'[Value] ),
ALL ( 'FactSprint' ),
TOPN ( 6, dimTableFiltered, [dimSprintEndDateKey], DESC )
)
Use it on a matrix visual (or pivottable). Be sure to put 'FactSprint'[dimSprintKey] or 'FactSprint'[SprintPK] on Rows and [Total Value Last Six Sprints] on Values.

SSAS Tabular DAX using of IF Statement

I have this query written in SQL:
SELECT
CustomerId,
CustomerType,
CASE WHEN CustomerStatus = 'VIP'
THEN CustomerDiscountType
ELSE NULL
END AS CustomerDiscountType
FROM Customer
And I would like to write this in DAX query:
I know that I can write like this:
EVALUATE
(
SUMMARIZE
(
'Customer',
'Customer'[CustomerId],
'Customer'[Type],
'Customer'[DiscountType],
"Customer VIP", IF('Customer'[Status] = "VIP", 'Customer'[DiscountType], BLANK())
)
)
But when I write if condition I need include attribute 'Customer'[DiscountType] in that query too, but I would like to write the column name of that IF statement
"DiscountType", but it isn't possible for me like below.
EVALUATE
(
SUMMARIZE
(
'Customer',
'Customer'[CustomerId],
'Customer'[Type],
"DiscountType", IF('Customer'[Status] = "VIP", 'Customer'[DiscountType], BLANK())
)
)
It failed with this error because of existing DiscountType column:
Function 'SUMMARIZE' cannot add column [DiscountType] since it already exists.
Instead of using SUMMARIZE you can use SELECTCOLUMNS function. I think the error is caused because the IF function returns DiscountType column and it already exists in your Customer table. Also I am unsure if SUMMARIZE works without any aggregation like used in your DAX expression.
Try this expression:
EVALUATE
(
SELECTCOLUMNS (
'Customer',
"CustomerId", 'Customer'[CustomerId],
"Type", 'Customer'[Type],
"DiscountType", IF ( 'Customer'[Status] = "VIP", 'Customer'[DiscountType], BLANK () )
)
)
UPDATE: OP tells via comments the version used is SSAS 2014 which doesn't support SELECTCOLUMNS function.
You can use a mix of SUMMARIZE and ADDCOLUMNS functions to get the expected result.
EVALUATE
(
SUMMARIZE (
ADDCOLUMNS (
ADDCOLUMNS (
DISTINCT ( Customer[CustomerID] ),
"Type", CALCULATE ( VALUES ( Customer[Type] ) ),
"Status", CALCULATE ( VALUES ( Customer[Status] ) ),
"DiscountType1", CALCULATE ( VALUES ( Customer[DiscountType] ) )
),
"DiscountType", IF ( [Status] = "VIP", [DiscountType1], BLANK () )
),
[CustomerId],
[Type],
[DiscountType]
)
)
It is not tested but should work, let me know if this helps for you.