Dynamic performance % dax formula - dynamic

Hope you all are doing well and safe!!
I have a question regarding Power BI dax. I want to create a dax measure for performance percentage in which numerator and denominator will be as per user filter.
Case 1: I want to create a dax measure for performance % (Current Month Sales / Dec'20 Sales) in which current month value will be depending upon user drop down filter and denominator will be fixed with Dec'20 sales value.
Case 2: I want to create a dax measure for performance % (Current Month Sales / Previous Month Sales) in which current month value will be depending upon user drop down filter and denominator will be as per previous month depending upon month selection done by user.
Thanks in advance :)

Try these measures
Case 1 =
DIVIDE (
[Measure],
CALCULATE (
[Measure],
Dates[Calendar Year Number] = 2020,
Dates[Month Number] = 12,
REMOVEFILTERS ( Dates )
)
)
Case 2 =
VAR SelectedMonth =
CALCULATE ( MAX ( Dates[Calendar Year Month Number] ), ALLSELECTED ( Dates ) )
VAR PreviousMonth =
CALCULATE (
MAX ( Dates[Calendar Year Month Number] ),
Dates[Calendar Year Month Number] < SelectedMonth,
REMOVEFILTERS ( Dates )
)
VAR Result =
DIVIDE (
[Measure],
CALCULATE (
[Measure],
Dates[Calendar Year Month Number] = PreviousMonth,
REMOVEFILTERS ( Dates )
)
)
RETURN
Result

Related

Separate by month, with each month having data from beginning of time to end of month in question - SQL

I currently have a window function that takes all my data and finds the latest value (amount) for each account and then averages this across all accounts.
Now I want to segment by month. The problem is if there has been no data for the account in the month specified we need to get the last possible value used. Therefore we need each month to segment from the beginning of the month to the chosen month. Currently the query provides one value 'average amount'. Ideally I would like this average value for each month from inception
SELECT AVG(amount) as "average amount"
FROM (
SELECT *
FROM(
SELECT account_no,amount,_date,row_number() over(partition by account_no order by _date desc) as rn, source
FROM ('another subquery too long to write out fully') k
) j
WHERE j.rn = 1
) l

Translating SQL with join and window function to DAX

I have a working SQL query, but it needs to be translated to DAX and I'm struggling.
This is what I'm trying to achieve:
I have agreements running from a startdate to an enddate in a fact table. An agreement running for a whole year counts as 1, meaning DATEDIFF(startdate, enddate) / 365.0 gives the "weight" of the agreement. It is needed to look at any given month and get the sum of the trailing year's total agreement weights. I also have a dimension table related to the fact table with all dates (single days and in which year/month they belong), which gives me the possibility to perform the following SQL query to get exactly what I want:
SELECT
sub.yearMonth
,SUM(sub.[cnt]) OVER (ORDER BY sub.[yearMonth] DESC ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) / 365.0 AS [runningYear]
FROM
(SELECT
d.yearMonth
,COUNT(*) AS [cnt]
FROM Agreememts AS a
INNER JOIN Date AS d
ON d.date >= a.startddate AND d.date <= a.enddate
GROUP BY d.yearMonth
) AS sub
I tried to replicate this in a DAX measure ending up with the following:
AgreementWeights:=
CALCULATE (
CALCULATE (
COUNTROWS ( 'Agreements' );
FILTER (
'Agreements';
'Agreements'[startdate] <= MAX ( 'Date'[date] )
&& 'Agreements'[enddate] >= EDATE ( MAX( 'Date'[date] ); -12)
)
);
CROSSFILTER ( 'Agreements'[receiveddate]; 'Date'[sys_date_key]; NONE )
)
The last line is to cut the relationship from the recieveddate to the date dimension, which is irrelevant here. This DAX query yields too many rows, but gives the correct result when divided like (result/365)*100 and I simply cannot figure out why.
An example of the fact table Agreements:
ID startdate enddate recieveddate
0 10-04-2014 12-06-2015 10-03-2014
1 11-06-2014 11-07-2014 11-05-2014
An example of the dimension table Date:
ID date yearMonth sys_date_key
0 10-04-2014 April2014 10042014
1 11-04-2014 April2014 11042014
Thanks :)

Difference between two measure dax

I have a measure that calculates previous recorded sales now I would like to work out the difference between period sales against previous period sales, I tried simple subtraction but I get error message..
Any suggestions please..
Thanks
Sales Change:= sales[sales]-Previous Day Sales
Previous Day Sales :=
CALCULATE (
SUM ( Sales[Sales] ),
FILTER (
ALL ( Sales ),
Sales[Date]
= CALCULATE (
MAX ( Sales[Date] ),
FILTER (
ALL ( Sales ),
COUNTROWS ( FILTER ( Sales, EARLIER ( Sales[Date] ) < Sales[Date] ) )
)
)
)
)
If you are creating a measure you have to aggregate the Sales[Sales] using the SUM() function.
Sales Change := SUM(Sales[Sales])-[Previous Day Sales]
While creating measures you cannot refer to column values without an aggregation. Measures run in multiple contexts and the Sales[sales] column value cannot be calculated in a different context than the row context.

Fiscal Year To-Date in Where Clause (T-SQL)

Company's Fiscal Year: July 1 - June 30
I have a query where I am trying to capture aggregate # of units and $ revenue by product and cost center for the fiscal year-to-date. It will run on the 1st of the month and look through the last day of the previous month. Fiscal year does not appear in the report - it is criteria.
Mix of pseudocode and SQL:
Where
If datepart(mm,getdate()) - 1 < 7
THEN
transaction_post_date BETWEEN 7/1/ previous year AND dateadd(day,-(day(getdate()),getdate())
Else
transaction_post_date BETWEEN 7/1/current year AND dateadd(day,-(day(getdate()),getdate())
Am I on the write track? How do I write the SQL for a specific date on a year that depends on SQL - 7/1/current year?
I am weak using variables and do not even know if I have access to create them on the SQL Server DB, which is rather locked down. Definitely can't create a function. (I'm a business analyst.)
UPDATE, Fiscal year goes forward, so July 1, 2010, is Fiscal Year 2011.
I think this works:
Year(dateadd(month,6,htx.tx_post_date)) = Year(DateAdd(Month, 5, GetDate()))
Feeback?
And now I've been asked to add Fiscal Year-To-Date fields for quantity and revenue to the following query which gave me totals for
Select
inv.ITEM_CODE
, inventory.ITEM_NAME
, cc.COST_CENTER_CODE
, tx.REV_CODE_ID
, tx.PRICE
, tx.ITEM_SALE_ID
, sum(tx.quantity)
, sum(tx.amount)
from
transactions tx
inner join inventory inv on inv.item_id = tx.item_id
left outer join cost_center cc on cc.cost_center_id = tx.cost_center_id
where
DATEPART(mm, tx.tx_date) = DATEPART(mm,dateadd(m,-1,getdate()))
and DATEPART(yyyy, tx.tx_date) = DATEPART(yyyy,dateadd(m,-1,getdate()))
group by
inv.ITEM_CODE
, inventory.ITEM_NAME
, cc.COST_CENTER_CODE
, tx.REV_CODE_ID
, tx.PRICE
, tx.ITEM_SALE_ID
I need to add the fiscal year-to-date quantity and and amount columns to this report. Would a correlated subquery by the way to go? Would the joins be tricky? I've never used a subquery with an aggregation/grouping query.
Thanks for all the previous help.
Here is how I would do it if I needed to group by Fiscal Year:
Group by Year(DateAdd(Month, -6, TransactionDate))
May be not exactly it, but you get the idea.
I would add a calculated column to your table called FiscalYear (with the proper calculation) and select based on that column
I believe the easiest way is to do this in two steps. Use the WHERE Clause to filter your YTD and then a GROUP BY to group by FY. Since your FY begins in July(7) then increment the FY if the month is greater than June(6).
WHERE CLAUSE:
WHERE
DATEDIFF(DAY, transaction_post_date, Cast(Month(GetDate()) as varchar) +
'/' + Cast(Day(GetDate()) as varchar) + '/' + CAST(Case WHEN
MONTH(transaction_post_date) > 6 then YEAR(transaction_post_date) + 1 else
Year(transaction_post_date) end as varchar)) >=0
GROUP BY CLAUSE:
GROUP BY CASE WHEN MONTH(transaction_post_date) > 6 then
Year(transaction_post_date) + 1 else YEAR(transaction_post_date) end

Last three months average for each month in PostgreSQL query

I'm trying to build a query in Postgresql that will be used for a budget.
I currently have a list of data that is grouped by month.
For each month of the year I need to retrieve the average monthly sales from the previous three months. For example, in January I would need the average monthly sales from October through December of the previous year. So the result will be something like:
1 12345.67
2 54321.56
3 242412.45
This is grouped by month number.
Here is a snippet of code from my query that will get me the current month's sales:
LEFT JOIN (SELECT SUM((sti.cost + sti.freight) * sti.case_qty * sti.release_qty)
AS trsf_cost,
DATE_PART('month', st.invoice_dt) as month
FROM stransitem sti,
stocktrans st
WHERE sti.invoice_no = st.invoice_no
AND st.invoice_dt >= date_trunc('year', current_date)
AND st.location_cd = 'SLC'
AND st.order_st != 'DEL'
GROUP BY month) as trsf_cogs ON trsf_cogs.month = totals.month
I need another join that will get me the same thing, only averaged from the previous 3 months, but I'm not sure how.
This will ALWAYS be a January-December (1-12) list, starting with January and ending with December.
This is a classic problem for a window function. Here is how to solve this:
SELECT month_nr
,(COALESCE(m1, 0)
+ COALESCE(m2, 0)
+ COALESCE(m3, 0))
/
NULLIF ( CASE WHEN m1 IS NULL THEN 0 ELSE 1 END
+ CASE WHEN m2 IS NULL THEN 0 ELSE 1 END
+ CASE WHEN m3 IS NULL THEN 0 ELSE 1 END, 0) AS avg_prev_3_months
-- or divide by 3 if 3 previous months are guaranteed or you don't care
FROM (
SELECT date_part('month', month) as month_nr
,lag(trsf_cost, 1) OVER w AS m1
,lag(trsf_cost, 2) OVER w AS m2
,lag(trsf_cost, 3) OVER w AS m3
FROM (
SELECT date_part( 'month', month) as trsf_cost -- some dummy nr. for demo
,month
FROM generate_series('2010-01-01 0:0'::timestamp
,'2012-01-01 0:0'::timestamp, '1 month') month
) x
WINDOW w AS (ORDER BY month)
) y;
This is requires that no month is ever missing! Else, have a look at this related answer:
How to compare the current row with next and previous row in PostgreSQL?
Calculates correct average for every month. If only two previous moths then devide by 2, etc. If no prev. months, result is NULL.
In your subquery, use
date_trunc('month', st.invoice_dt)::date AS month
instead of
DATE_PART('month', st.invoice_dt) as month
so you can sort months over the years easily!
More info
Window function lag()
date_trunc()