Dynamic X-Axis Date Range Based on Disconnected Slicer - ssas

I have an issue that I need a hand with. I am using a disconnected slicer based off of this table
Time Frame :=
DATATABLE("ID", Integer, "Time Frame", string
, {
{1, "3 Month"}
, {2, "6 Month"}
, {3, "9 Month"}
, {4, "12 Month"}
})
that looks like this:
Using a few DAX measures:
Sum Of Paid := sum(Data[Paid])
Sum Of Paid 3 Month Period :=
CALCULATE (
[Sum Of Paid],
DATESINPERIOD ( Data[Date], LASTDATE ( Data[Date] ), -3, MONTH )
)
Sum Of Paid 6 Month Period :=
CALCULATE (
[Sum Of Paid],
DATESINPERIOD ( Data[Date], LASTDATE ( Data[Date] ), -6, MONTH )
)
Sum Of Paid 9 Month Period :=
CALCULATE (
[Sum Of Paid],
DATESINPERIOD ( Data[Date], LASTDATE ( Data[Date] ), -9, MONTH )
)
Sum Of Paid 12 Month Period :=
CALCULATE (
[Sum Of Paid],
DATESINPERIOD ( Data[Date], LASTDATE ( Data[Date] ), -12, MONTH )
)
Slicer - Paid Per Period :=
VAR selection =
IF (
HASONEVALUE ( 'Time Frame'[Time Frame] ),
VALUES ( 'Time Frame'[Time Frame] ),
"All"
)
VAR ThreeMonth = [Sum of Paid 3 Month Period]
VAR SixMonth = [Sum of Paid 6 Month Period]
VAR NineMonth = [Sum of Paid 9 Month Period]
VAR TwelveMonth = [Sum of Paid 12 Month Period]
RETURN
SWITCH (
TRUE (),
selection = "3 Month", ThreeMonth,
selection = "6 Month", SixMonth,
selection = "9 Month", NineMonth,
selection = "12 Month", TwelveMonth,
TwelveMonth
)
I can simulate a slicer and display 3, 6, 9 and 12 month aggregates depending on the users selection. These work just fine in cards, choropleths and almost everything I've needed them for. My issue is trying to create line graphs, bar charts, etc that have a date range on the x-axis. I can't for the life of me figure out how to replicate the period referenced in the DAX measure to dynamically set the x-axis.
I've tried a few approaches that seem like they should work but do not:
3 Month Period :=
CALCULATE (
VALUES(Data[Date]),
DATESINPERIOD ( Data[Date], LASTDATE ( Data[Date] ), -3, MONTH )
)
Any help is appreciated.
Thanks

You might want to try this one:
3 Month Period :=
CALCULATE (
[Sum Of Paid],
KEEPFILTERS (
DATESINPERIOD (
Data[Date],
CALCULATE (
MAX ( Data[Date] ),
ALLSELECTED ()
),
-3,
MONTH
)
)
)

Related

DAX Variable Scope

I am working on a problem involving the scope of DAX variables. My code defines the hire date and termination date of employees and them implements logic based on the result. My problem is that the scope of my variable is NOT in the row context of each employee, rather, its shows the minimum hiredate and maximum hiredate for ALL employees.
Employment Cases =
VAR PeriodStart =
DATE ( 2022, 01, 01 )
VAR PeriodEnd =
DATE ( 2022, 03, 31 )
VAR Hire =
MIN ( attr_Tkpr_vw[TkprDateHire] ) // How do I define this variable so that it results in each employees hire date?
VAR Term =
MIN ( attr_Tkpr_vw[TkprDateTerm] ) // How do I define this variable so that it results in each employees term date?
VAR ReportPeriod =
DATEDIFF ( PeriodStart, PeriodEnd, MONTH )
VAR S3 =
DATEDIFF ( Hire, PeriodEnd, MONTH ) / ReportPeriod
VAR S4 =
DATEDIFF ( Hire, Term, MONTH )
RETURN
SELECTCOLUMNS (
attr_Tkpr_vw,
"EmpID", attr_Tkpr_vw[TkprNumber],
"Hire", attr_Tkpr_vw[TkprDateHire],
"Term", attr_Tkpr_vw[TkprDateTerm],
"Hire Test", Hire,
"Term Test", Term,
"Employment Period",
SWITCH (
TRUE (),
AND (
AND (
attr_Tkpr_vw[TkprDateHire] >= PeriodStart,
attr_Tkpr_vw[TkprDateHire] <= PeriodEnd
),
attr_Tkpr_vw[TkprDateTerm] >= PeriodEnd
), S3,
AND (
AND (
attr_Tkpr_vw[TkprDateHire] >= PeriodStart,
attr_Tkpr_vw[TkprDateHire] <= PeriodEnd
),
AND (
attr_Tkpr_vw[TkprDateTerm] >= PeriodStart,
attr_Tkpr_vw[TkprDateTerm] <= PeriodEnd
)
), S4
)
)
I suspect an iterator function is missing. I tried enclosing the SELECTCOLUMNS expression with CALCULATETABLE. This did not work.
The result set shows that in each case the Hire and Term dates are calculated for the entire table, not each individual.
enter image description here
You need to move the variable scope to inside the SELECTCOLUMNS:
SELECTCOLUMNS (
attr_Tkpr_vw,
"EmpID", attr_Tkpr_vw[TkprNumber],
"Hire", attr_Tkpr_vw[TkprDateHire],
"Term", attr_Tkpr_vw[TkprDateTerm],
"Hire Test", VAR Hire = attr_Tkpr_vw[TkprDateHire]
RETURN Hire,
If you want to do MIN functions then I believe you need a CALCULATE statement to transition the row context to a filter context:
SELECTCOLUMNS (
attr_Tkpr_vw,
"EmpID", attr_Tkpr_vw[TkprNumber],
"Hire", attr_Tkpr_vw[TkprDateHire],
"Term", attr_Tkpr_vw[TkprDateTerm],
"Hire Test", VAR Hire = CALCULATE(MIN(attr_Tkpr_vw[TkprDateHire]))
RETURN Hire,

How to Show Previous Year on Dynamic Date

I have a database that has customer, product, date and volume/revenue data. I'd like to create two NEW columns to show the previous year volume and revenue based on the date/customer/product.
I've tried unioning two views, one that has dates (unchanged) and a second view that creates a CTE where I select the dates minus one year with another select statement off of that where VOL and REV are renamed VOL_PY and REV_PY but the data is incomplete. Basically what's happening is the PY data is only pulling volume and revenue if there is data in the prior year (for example if a customer didn't sell a product in 2021 but DID in 2020, it wouldn't pull for the VOL_PY for 2020 - because it didn't sell in 2021). How do I get my code to include matches in dates but also the instances where there isn't data in the "current" year?
Here's what I'm going for:
[EXAMPLE DATA WITH NEW COLUMNS]
CURRENT YEAR VIEW:
SELECT
CUSTOMER
,PRODUCT
,DATE
,VOL
,REV
,0 AS VOL_HL_PY
,0 AS REV_DOLS_PY
,DATEADD(YEAR, -1, DATE) AS DATE_PY FROM dbo.vwReporting
PREVIOUS YEAR VIEW:
WITH CTE_PYFIGURES
([AUTONUMBER]
,CUSTOMER
,PRODUCT
,DATE
,VOL
,REV
,DATE_PY
) AS
(
SELECT b.*
, DATEADD(YEAR, 1, DATE) AS DATE_PY
FROM dbo.basetable b
)
SELECT
v.CUSTOMER
,v.PRODUCT
,v.DATE
,0 AS v.VOL
,0 AS v.REV
,CTE.VOL_HL AS VOL_HL_PY
,CTE.REV_DOLS AS REV_DOLS_PY
,DATEADD(YEAR,-1,CTE.PERIOD_DATE_PY) AS PERIOD_DATE_PY
FROM dbo.vwReporting AS v
FULL OUTER JOIN CTE_PYFIGURES AS CTE ON CTE.CUSTOMER=V.CUSTOMER AND CTE.PRODUCT=V.PRODCUT AND CTE.DATE_PY=V.DATE
You need to offset your current year's data to one year forward and then union it with the current data, placing zeroes for "other" measures (VOL and REV for previous year and VOL_PY and REV_PY for current year). Then do aggregation. This way you'll have all the dimensions' values that were in current or previous year.
with a as (
select
CUSTOMER
, PRODUCT
, [DATE]
, VOL
, REV
, 0 as vol_py
, 0 as rev_py
from dbo.vwReporting
union all
select
CUSTOMER
, PRODUCT
, dateadd(year, 1, [DATE]) as [DATE]
, 0 as VOL
, 0 as REV
, vol as vol_py
, rev as rev_py
from dbo.vwReporting
)
select
CUSTOMER
, PRODUCT
, [DATE]
, VOL
, sum(vol) as vol
, sum(rev) as rev
, sum(vol_py) as vol_py
, sum(rev_py) as rev_py
from a
group by
CUSTOMER
, PRODUCT
, [DATE]
, VOL

DAX Query on (Day Over Day)

I have the Sales table and a Date table
I wrote the below query to calculate the DOD Sales
Sales Volume := SUM([Sales])
Sales Volume (Prev) := CALCULATE([Sales Volume], PREVIOUSDAY('Date'[Date])
Sales Volume (DOD) = DIVIDE([Sales Volume]-[Sales Volume (Prev)],[Sales Volume (Prev)])
However, these query above will calculate DOD based on continuous day of a month. My concern is I would like to calculate only those Order Date. For example, I would like to compare Sales on 4/12/2016 and 1/12/2016. ((50-20)/20).
How should i amend the query to achieve that?
You have to create a calculated column to get the previous date:
Previous Date =
CALCULATE (
MAX ( [Order Date] ),
FILTER ( ALL ( 'Table' ), [Order Date] < EARLIER ( 'Table'[Order Date] ) )
)
Then just create the measures with the following expressions:
Sales Volume := SUM('Table'[Sales])
Sales Volume Prev :=
CALCULATE (
SUM ( [Sales] ),
FILTER ( ALL ( 'Table' ), 'Table'[Order Date] = MAX ( [Previous Date] ) )
)
Sales Volume (DOD) :=
DIVIDE ( [Sales Volume] - [Sales Volume Prev], [Sales Volume Prev] )
Let me know if this helps.

DAX Measure - Summing up values between start-end dates in the same table

I have an "Assignments" Table like this:
Date End Date Allocation1111 Alex AA 11/20/2016 12/30/2016 0.52222 Eric BB 10/20/2016 11/30/2016 0.43333 John CC 10/20/2016 12/30/2016 12222 Eric DD 11/20/2016 1/1/2017 0.5
I also have a simple "Date" Table which DOES NOT have a relationship with the Assignments Table like this:
Date Month Month_Text Year Month-Year10/1/2016 10 Oct 2016 Oct-1610/2/2016 10 Oct 2016 Oct-1610/3/2016 10 Oct 2016 Oct-1610/4/2016 10 Oct 2016 Oct-16
Than I have the following DAX measure:
==============================
Sum of Assignments :=CALCULATE ( SUMX ( Assignments_Tbl, Assignments_Tbl[Allocation] ), FILTER ( VALUES ( Date_Tbl ), Date_Tbl[Date] >= MINX ( Assignments_Tbl, Assignments_Tbl[Start Date] ) && Date_Tbl[Date] <= MAXX ( Assignments_Tbl, Assignments_Tbl[End Date] ) )) * CALCULATE ( DISTINCTCOUNT ( Date_Tbl[Month] ), FILTER ( VALUES ( Date_Tbl ), Date_Tbl[Date] >= MINX ( Assignments_Tbl, Assignments_Tbl[Start Date] ) && Date_Tbl[Date] <= MAXX ( Assignments_Tbl, Assignments_Tbl[End Date] ) ) )
==============================
All seems OK when I have the Start Date and End Date as part of my Pivot Table like below:
Sum of Assignments in a pivot table with Start/End Dates
HOWEVER, if I remove the Start Date and End Date from the pivot table, the measure is calculating incorrectly and I can't find why.
For instance, as the pic below, the red circles show 0.9 for a person name "Eric" in in Oct-2016, instead of 0.4.
Sum of Assignments measure calculating incorrectly
I tried many things, but got stuck on this measure. Any idea?
After some deeper investigation, here is the proper measure:
New Measure =
SUMX (
Assignments_Tbl,
CALCULATE (
SUM ( Assignments_Tbl[Allocation] ) * DISTINCTCOUNT ( Date_Tbl[Month-Year] ),
FILTER (
VALUES ( Date_Tbl ),
Date_Tbl[Date] >= EARLIER ( Assignments_Tbl[Start Date], 1 )
&& Date_Tbl[Date] <= EARLIER ( Assignments_Tbl[End Date], 1 )
)
)
)

DAX Cumulative Total Comparison from Different Tables

How do I create a DAX measure that will show me the First Receipt Date where the Receipt Balance is greater than or equal to the Payment Balance?
For example, for Jun, I want the [Payment Receipt Date Avg] measure to show as Jan because the Receipt Balance is 10 which is greater than the Payment Balance of 8.
For Aug, it would show as Feb because that is the first date where the Receipt Balance is at least the Payment Balance of 13.
Desired Result:
Data Model
Table: Po Receipt
Table: Payment
Attempted Solution
I already have the below measures defined:
Receipt Balance:
=CALCULATE
(
SUM(PoReceipt[Quantity Received]),
FILTER
(
ALL ( PaymentDates ),
PaymentDates[Payment_FullDate] <= MAX ( PaymentDates[Payment_FullDate] )
)
)
Payment Balance:
=CALCULATE
(
SUM(Payment[Payment Amount]),
FILTER
(
ALL ( PaymentDates ),
PaymentDates[Payment_FullDate] <= MAX ( PaymentDates[Payment_FullDate] )
)
)
Create calculated columns to get the first date which has a net receipt running total (i.e. receipts less payments running total) greater than the payment amount in the current row context. The calculated columns will need to do the following:
Return the running total of [Payment Amount] for each [PO Num]. The EARLIER function is used so that for each row in the outer context, you sum all rows in the inner context where the inner row has a [Payment Date] less than or equal to the outer row, and the inner row's [Po Num] is equal to that of the outer row.
Return a summary table based on the PoReceipt table, which has an extended column "Receipt Balance Calc". The extended column calculates the running total of the PoReceipt[Quantity Received] similar to step 1. The summary table is grouped by the columns [Po Num] and [Receipt Date] to avoid performing the same calculation more than once (since there are multiple rows with the same [Po Num] due to the [Receipt Num] column).
Filter the result to only include rows where the Receipt Balance is greater than or equal to the Payment Balance.
See DAX code for calculated columns:
Payment[Payment Balance Calc]
=CALCULATE (
SUM ( Payment[Payment Amount] ),
FILTER (
Payment,
Payment[Payment Date] <= EARLIER ( Payment[Payment Date] )
&& Payment[Po Num] = EARLIER ( Payment[Po Num] )
)
)
Payment[Payment Receipt Date]
=CALCULATE (
MIN ( PoReceipt[Receipt Date] ),
ALL ( PaymentDates ),
FILTER (
ADDCOLUMNS (
SUMMARIZE (
PoReceipt,
PoReceipt[Po Num],
PoReceipt[Receipt Date]
),
"Receipt Balance Calc",
CALCULATE (
SUM ( PoReceipt[Quantity Received] ),
FILTER (
PoReceipt,
PoReceipt[Receipt Date] <= EARLIER ( PoReceipt[Receipt Date] )
&& PoReceipt[Po Num] = EARLIER ( PoReceipt[Po Num] )
)
)
),
[Receipt Balance Calc] >= EARLIER ( Payment[Payment Balance Calc] )
)
)
Finally, create the below measure to calculate the weighted average of the receipt dates:
Payment Receipt Date Avg:=
SUMX (
Payment,
Payment[Payment Amount] * Payment[Payment Receipt Date]
/ SUM ( Payment[Payment Amount] )
)