DAX - Finding Previous Year Equivalent, based on Fiscal Calendar retaining time/row hierarchy - dax

I have 2 tables that have a many to one relationship defined by a 'FiscalWeekEndDate' value, like so;
WordsTable
FiscalWeekEndDate | WordGroup | IndexedVolume
01/01/2017 | Dining | 1,000
01/01/2017 | Shopping | 2,000
08/01/2017 | Dining | 2,000
08/01/2017 | Sports | 5,000
FiscalDatesTable
FiscalWeekEndDate | FiscalWeek | FiscalMonth | FiscalQuarter | FiscalYear
01/01/2017 | 21 | 5 | 2 | 2017
08/01/2017 | 22 | 5 | 2 | 2017
I'm trying to create a simple PY equivalent measure in DAX (previous year), that works at all levels of time hierarchy - i.e. PY for chosen fiscal week, month, quarter or year. I don't want a YTD (year to date) measure.
This is what I have so far;
Previous Year Indexed Volume:=
CALCULATE([IndexedVolume],
FILTER(ALL('FiscalDatesTable'),'FiscalWeeksTable'[FiscalWeek]=
MAX('FiscalDatesTable'[FiscalWeek]) && 'FiscalDatesTable'[FiscalYear] =
MAX('FiscalDatesTable'[FiscalYear]) - 1))
Which is returning this type of result;
Fiscal Year 2017: 7,000
Fiscal Quarter 2: 7,000
Fiscal Month 5: 7,000
Fiscal Week 22: 7,000
Fiscal Week 21: 3,000
Basically, the Max Fiscal Week value (22: 7,000) is returned for the Month, Quarter or Year dimension. I understand that's a problem due to my DAX Filter, but unsure what else to try.
The desired result would give me the correct Previous Year IndexedVolume value, regardless of the time dimension chosen. i.e. like below;
Fiscal Year 2017: 10,000
Fiscal Quarter 2: 10,000
Fiscal Month 5: 10,000
Fiscal Week 22: 7,000
Fiscal Week 21: 3,000

A few hours of research and I finally cracked it by introducing a 'PreviousFiscalWeekEndDate' into the logic.
Here is the approach if anyone finds it useful.
Previous Year Indexed Volume:=
CALCULATE([IndexedVolume],
FILTER (
ALL ( 'FiscalDatesTable' ),
CONTAINS (
VALUES ( 'FiscalDatesTable'[PreviousYearFiscalWeekEndDate] ),
'FiscalDatesTable'[PreviousYearFiscalWeekEndDate],
'FiscalDatesTable'[FiscalWeekEndDate]
)
)
)

Related

Access Report: How to group on one field, but sort by another?

I've read through similar questions and they don't seem to quite fit my issue or they're in a different environment.
I'm working in MS-Access 2016.
I have a customer complaints report which has fields: year, month, count([complaint #]), complaint_desc.
(complaint # is the literal ID number we assign to each complaint entered into the table)
I grouped the report by year and month and then grouped by complaint_desc and for each desc did a count of complaint number, and then did a count of complaint # to add up total complaints for the month and stuck it in the month footer which gives a result of something like this:
2020 03 <= (this is the month group header)
complaint desc | count of complaints/desc
---------------------------------------------
electrical | 2 {This section is
cosmetic | 6 {in the Complaint_desc
mechanical | 1 {group footer
---------------------------------------------
9 <= (this is month group footer)
repeating the group for each month
This is all good. What I want to do is to sort the records within the complaint desc group in descending order of count(complaint#) so that it looks like:
2020 03
complaint desc | count of complaints/category
---------------------------------------------
cosmetic | 6
electrical | 2
mechanical | 1
---------------------------------------------
9
However nothing I do seems to work, the desc group's built-in sort "a on top" overrides sorting in the query. adding a sort by complaint# is ignored also. I tried to add a sort by count(complaint#) and access told me I can't have an aggregate function in an order by (but I think it would have been overridden anyway). I also tried to group by count(complaint#) also shot down as aggregate in a group by. Tried moving complaint_desc and count(complaint#) to the complaint# group header and it screwed up the total count in the month footer and also split up the complaint desc's defeating it's original purpose...
I really didn't think this change was going to be a big deal, but a solution has evaded me for a while now. I've read similar questions and tried to follow examples but they didn't lead to my intended result.
Any Idea?
I figured it out! Thank you to #UnhandledException who got me thinking on the right track.
So here's what I did:
The original query the report was based on contained the following:
Design mode:
Field | Year | Month | Complaint_Desc | Complaint# |
Total | Group By | Group By | Group By | Group By |
Sort | | | | |
or in SQL:
SELECT Year, Month, [tbl Failure Mode].[Code description], [Complaint Data Table].[Complaint #]
FROM [tbl Failure Mode] RIGHT JOIN [Complaint Data Table] ON [tbl Failure Mode].[ID code] = [Complaint Data Table].[Failure Mode]
GROUP BY Year, Month, [tbl Failure Mode].[Code description], [Complaint Data Table].[Complaint #];
And then I was using the report's group and sort functions to make it show how I wanted except for the hiccup I mentioned.
I made another query based upon that query:
Design mode:
Field | Year | Month | Complaint_Desc | Complaint# |
Total | Group By | Group By | Group By | Count |
Sort | Descending | Descending | | Descending |
or in SQL:
SELECT [qry FailureMode].Year, [qry FailureMode].Month, [qry FailureMode].[Complaint_description], Count([qry FailureMode].[Complaint #]) AS [CountOfComplaint #], [qry FailureMode].Complaint
FROM [qry FailureMode]
GROUP BY [qry FailureMode].Year, [qry FailureMode].Month, [qry FailureMode].[Code description], [qry FailureMode].Complaint
ORDER BY [qry FailureMode].Year DESC , [qry FailureMode].Month DESC , Count([qry FailureMode].[Complaint #]) DESC;
Then I changed the report structure:
I eliminated the Complaint_Desc group, moved complaint_desc and CountofComplaint# (which is now not a function but it's own calculated field from my new query) to the DETAIL section of the report. Then I deleted my 2nd count(complaint#) that was in the month footer as a total for each month and replaced it with the "AccessTotalsCountOfComplaint #" which is =Sum([CountOfComplaint #]) which I had access auto-create by right-clicking on the CountofComplaint_Desc in details scrolling to "Total" and clicking on "Sum". (I deleted the extra AccessTotalsCountOfComplaint#'s that were outside of the Month Group Footer that I needed it for...)
Et Voila
I hope this helps someone else, and thank you again to Unhandled Exception who pointed me in the right direction.

power bi dax - previous quarter value?

I have a simple table with data in the following format:
category | score | date
cat1 | 3 | 31/3/2019
cat2 | 9 | 31/3/2019 Q1 data
cat3 | 7 | 31/3/2019
...
cat1 | 6 | 30/6/2019
cat2 | 4 | 30/6/2019 Q2 data etc.
cat3 | 1 | 30/6/2019
Basically, I have many rows for quarterly data (scores for different categories) where the date column references the actual quarter. I have a chart where I'm showing the values from the latest quarter (most recent data), but I need a column to give me previous quarter's score. I found out about PREVIOUSQUARTER, which looked like an easy trick, but it returns blanks.
prevQtr = CALCULATE(SUM(data[score]), PREVIOUSQUARTER(data[date]))
Can someone tell me what I'm doing wrong? I tried creating a date table, with continuous dates between the first and the last date of my column, it didn't help. No other time intelligence function seems to return anything, so I guess it's something generic. I tried the documentation, but it doesn't mention any limitation. What I'm looking for is:
category | score | date | prevQtr
cat1 | 3 | 31/3/2019 |
cat2 | 9 | 31/3/2019 |
cat3 | 7 | 31/3/2019 |
...
cat1 | 6 | 30/6/2019 | 3
cat2 | 4 | 30/6/2019 | 9
cat3 | 1 | 30/6/2019 | 7
Thanks
Screenshots:
Okay, three things here.
You need to reference your date dimension date column for the built in time intelligence functions. (Note, this also implies you should only use date fields from the date dimension. Hide 'data'[date] in your fact so you aren't tempted to use it.)
Since you're adding this as a calculated column, you're going to have to do some extra context manipulation.
Since there is no context being contributed by the date dimension here (you're only in row context of the fact table), you can't use a built-in time intelligence function effectively here.
So! My suggestion is to define your PrevQtr as a measure, rather than a column, in which case it will work with the small refactoring below:
PrevQtr =
CALCULATE (
SUM ( 'Data'[Score] ),
PREVIOUSQUARTER ( 'dateTable'[Date] ) // just referencing the date table here
)
If you must create a calculated column for this, and your data all follows the pattern in your sample of having values on the last day of the quarter, then I think this is the best bet for it:
PrevQtrColumn =
VAR CurrentRowDate = 'Data'[Date]
VAR PriorQuarterEnd = EOMONTH ( CurrentRowDate, -3 )
RETURN
CALCULATE (
SUM ( 'Data'[Score] ),
ALLEXCEPT ( 'Data', 'Data'[Category] ),
'Data'[Date] = PriorQuarterEnd
)
The big gotcha there is covered by the ALLEXCEPT. CALCULATE converts all row context to filter context, so your 'Data'[Score] values become filter context. ALLEXCEPT clears that, preserving only the [Category].
I would recommend just using a measure to achieve this, BUT.. your measure:
prevQtr = CALCULATE(SUM(data[score]), PREVIOUSQUARTER(data[date]))
Needs to reference your date table:
prevQtr = CALCULATE(SUM(data[score]), PREVIOUSQUARTER('dateTable'[date]))
This modification should do it.

Populating future dates in oracle table

I have attached tables, product and date.
Lets say my product table has data till yesterday i.e 05/31/2018
am trying to populate season table where I could do the calculation till 5/31/2018 where value = (value on same day last year/previous day last year) with Ch(a) and P(pen), however the data set was till 5/31/2018. my aim is to get data/calculation for 06/1/2018 till 12/31/2018 as well. how do i get the data for these future dates as I have the data to calculate these future dates in prod table.
appreciate if you can help.
Thank you!
You can generate a series of dates using CONNECT BY subquery like this one:
SELECT Start_date + level - 1 as my_date
FROM (
SELECT date '2018-01-01' as Start_date FROM dual
)
CONNECT BY Start_date + level - 1 <= date '2018-01-05'
Demo: http://www.sqlfiddle.com/#!4/072359/1
| MY_DATE |
|----------------------|
| 2018-01-01T00:00:00Z |
| 2018-01-02T00:00:00Z |
| 2018-01-03T00:00:00Z |
| 2018-01-04T00:00:00Z |
| 2018-01-05T00:00:00Z |

How to calculate day specific data from accumulated data

I have an Oracle table with values for two accounts and each record will have Date field. First day of the week will have only data relevant to the Day 1 but when we see the data for Day2 in a week it has accumulated data. So we need to subtract Day2 data from previous day data to calculate exact data for Day2.Similar approach for Day3..Day7.
Please suggest the best approach in SQL query to handle this requirement. I am very sorry to bother you. I am totally new to SQL.Really appreciate your valuable inputs.As an example, there are 6 columns with header are given below
Center Entity Bonus Year Period Incentive
MANUFACTURING NEW YORK 1200 FY18 31-12-2017 120
MANUFACTURING NEW YORK 1500 FY18 01-01-2018 250
MANUFACTURING NEW YORK 1800 FY18 01-01-2018 320
So assuming Dec 31, 2017 is the first day of the week, the data record will show only data for that day 1. When we move on to Day 2 of the week i.e. Jan 01, 2018, it has accumulated data which includes Day 1 and day2. So we need to subtract Day2 data from Day1 data to calculate exact data for data 2. 1500 - 1200 = 300 is the exact value for Day 2. Similar approach we need to follow for Day3, day4, Day5,Day6 and Day7.
Expected output is given below
Center Entity Bonus Year Period Incentive
MANUFACTURING NEW YORK 1200 FY18 01-01-2018 120
MANUFACTURING NEW YORK 300 FY18 01-01-2018 130
MANUFACTURING NEW YORK 300 FY18 01-01-2018 70
You could use a simple LAG() function with NVL().
select Center, Entity, Bonus,Year,Period,
Incentive - NVL( LAG(Incentive , 1) OVER ( ORDER BY Period ), 0) Incentive
FROM yourtable;
DEMO
You can do a self join with you table on period and do the subtraction from previous date's data.
looks like you have typo in the test data and result, the dates should be incremental as stated in description, but it has duplicate.
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE t
(Center varchar2(13), Entity varchar2(8), Bonus int, Year varchar2(4), Period DATE, Incentive int)
;
INSERT INTO t (Center, Entity, Bonus, Year, Period, Incentive)
VALUES ('MANUFACTURING', 'NEW YORK', 1200, 'FY18', DATE '2017-12-31', 120);
INSERT INTO t (Center, Entity, Bonus, Year, Period, Incentive)
VALUES ('MANUFACTURING', 'NEW YORK', 1500, 'FY18', DATE '2018-01-01', 250);
INSERT INTO t (Center, Entity, Bonus, Year, Period, Incentive)
VALUES ('MANUFACTURING', 'NEW YORK', 1800, 'FY18', DATE '2018-01-02', 320);
;
Query:
select t1.center,
t1.entity,
t1.bonus - nvl (t2.bonus,0) bonus,
t1.year,
t1.period,
t1.incentive - nvl(t2.incentive,0) incentive
from t t1
left outer join t t2
on t1.period = t2.period + 1
order by t1.period
Results:
| CENTER | ENTITY | BONUS | YEAR | PERIOD | INCENTIVE |
|---------------|----------|-------|------|----------------------|-----------|
| MANUFACTURING | NEW YORK | 1200 | FY18 | 2017-12-31T00:00:00Z | 120 |
| MANUFACTURING | NEW YORK | 300 | FY18 | 2018-01-01T00:00:00Z | 130 |
| MANUFACTURING | NEW YORK | 300 | FY18 | 2018-01-02T00:00:00Z | 70 |

SSRS - weekday sort in graph

I have a graph that compares transactions from the last 7 days (including the current day), to the 7 days before that.
However, I've noticed that sometimes during the day, the order of the days is incorrect.
When I open the report again it is the correct, without me doing anything to fix it.
The above graph was created on Sunday morning, and the Saturday and Friday values are switched around. Since it's Sunday morning, the graph should start on Monday, and end on Sunday.
Later on, it displayed as it should.
The data is as follows (unfortunately I could only pull data as it was when the graph was shown correctly.) There are 2 products that are grouped together in the graph.
Brand Date DepositAmount DayOfWeek WeekSeries
B 10/02/2014 1630 Monday Previous Week
A 11/02/2014 13717 Tuesday Previous Week
B 12/02/2014 2460 Wednesday Previous Week
A 13/02/2014 4941 Thursday Previous Week
A 18/02/2014 9194 Tuesday Current Week
B 19/02/2014 1947 Wednesday Current Week
A 20/02/2014 4185 Thursday Current Week
B 21/02/2014 273 Friday Current Week
A 22/02/2014 2521 Saturday Current Week
B 22/02/2014 1118 Saturday Current Week
A 23/02/2014 1438 Sunday Current Week
B 23/02/2014 105 Sunday Current Week
A 14/02/2014 4958 Friday Previous Week
B 14/02/2014 1023 Friday Previous Week
A 15/02/2014 2465 Saturday Previous Week
B 15/02/2014 1208 Saturday Previous Week
A 16/02/2014 3495 Sunday Previous Week
B 16/02/2014 680 Sunday Previous Week
A 17/02/2014 2726 Monday Current Week
B 17/02/2014 1177 Monday Current Week
A 10/02/2014 4938 Monday Previous Week
B 11/02/2014 1543 Tuesday Previous Week
A 12/02/2014 7891 Wednesday Previous Week
B 13/02/2014 5490 Thursday Previous Week
B 18/02/2014 4726 Tuesday Current Week
A 19/02/2014 9009 Wednesday Current Week
B 20/02/2014 459 Thursday Current Week
A 21/02/2014 6012 Friday Current Week
In SSRS, the graph is defined as follows:
Category Groups: DayOfWeek (sorted by Date (A to z))
Series Groups: WeekSeries (sorted by WeekSeries (A to Z)).
Any ideas what may be causing this issue?
I think the issue is in your Category Group sort - you are Grouping by DayOfWeek but then sorting by Date which has multiple values. The first row for Friday could get the Current Week Date or the Previous Week Date at random.
To fix this, for the Category Group sort, I would derive a "Relative DayOfWeek" value, something like:
= Abs ( DateDiff ( DateInterval.Day , Today() , Iif ( Fields!WeekSeries.Value = "Current Week" , Fields!Date.Value, DateAdd ( DateInterval.Day , 7 , Fields!Date.Value ) ) )

Resources