To calculate the average of Latest 12 weeks - ssas

I figured out how to calculate the average of latest 12 weeks volume in my data. But lets say the current year does not have 12 weeks, it only has 8 weeks then I want to take the remaining 4 weeks from the previous year to make it 12?
This is how my avg mdx query looks like:
Avg(
LastPeriods(
12,
Tail(
NonEmpty(
[Time].[Week].[Week].Members,
[Measures].[Vol ( Cases)]
),
1
).Item(0)
),
[Measures].[Vol ( Cases)]
)

I'm wondering if you could simplify and use the following within your measure?:
...
...
Tail(
NonEmpty(
[Time].[Week].[Week].Members,
[Measures].[Vol ( Cases)]
),
12
)
...
...

Related

MDX Add Condition to filter for the first 6 month of the year

I would like to find the top 10 most profitable customers in the first six months of the year 2021 (January through June) sorted by profit in descending order.
The following filter for all criteria except the months:
SELECT [measures].[Profit] ON 0,
TopCount(
[Customer.FullName].members,
10,
[measures].[Profit]
) ON 1
FROM [bike_sales]
WHERE ([OrderDate].[Year].[2021])
I tried extending the WHERE clause with [OrderDate].[Month].[1]:[OrderDate].[Month].[6], however the query results were not correct.
How can the above-mentioned query be adjusted to also filter for the first 6 month of 2021?
I ended up combining the month and year:
SELECT [measures].[Profit] ON 0,
TopCount(
[Customer.FullName].members,
10,
[measures].[Profit]
) ON 1
FROM [bike_sales]
WHERE ( [OrderDate.Days].[2021].[1].[1] : [OrderDate.Days].[2021].[6].[30] )

Pivot 12 Months dynamically backwards from current month

I have a table that looks like this:
CustName
Date
Hours
First
01/01/2021
12
Second
01/01/2021
10
Second
05/02/2021
1
Second
10/11/2021
14
I am trying to do a sum of hours per month per customer.
I figured out how to do this using a Pivot such as:
SELECT
CustName AS [Customer], ISNULL([January],0) AS [January], ISNULL([February],0) AS [February], ISNULL([March],0) AS [March]
FROM
(
SELECT
CustName,
DATENAME(MONTH, Date) AS [Month],
RegHrs
FROM TimeEntrySimpleList
) AS Src
PIVOT
(
SUM(Hours)
FOR [Month] IN ([January], [February], [March])
) AS Pvt
select* from TimeEntry
This works fine if I want to report say January - December in a static way, only ever showing the months I assign.
But what I want to do is have the last month column (March in my example), and show 12 months from the current backwards in the columns.
I'm guessing I would have to set the current month as a variable? And use it in the pivot .. but I'm not sure how / what to do. Use some sort of calc [month]*12 (reverse)?
Any tips would be appreciated!

Tracking Dynamic Weekly and Monthly Sales/Purchases given a fixed start date

I am new to Oracle SQL programming (programming in general actually) and recently discovered analytical functions. I am convinced I can use them to automate my daily, weekly, and monthly reporting.
I need help tracking week-on-week and month-on-month sales and purchases given a particular date as the start of the year or and/or week.
I have a table that maintains daily sales and purchases transactions by sales agents, how do I dynamically track revenue growth (since the year began) for week-on-week as well as month-on-month purchases per territory per region from our transactions table.
Our reporting week runs from Wednesday through Tuesday. I have managed to get some output(albeit not entirely accurate) for month-on-month but week-on-week is challenging me. How do maintain a dynamic counter of days in Oracle SQL that refreshes and starts another week each time it adds up to 7 days across the entire daily transactions table?
The interesting challenge I have in my head that I can't seem to put into code is what happens when I have a partial week's worth of data?! I want to be able to compare, say, 3 days worth of the current week's transactions with 3 days worth of the previous week's transactions. The same can be said for a partial month's worth of data.
This is the month-on-month analysis code I have managed so far.
WITH
monthly_revenue as (
SELECT
to_char(txn_date, 'YYYY-MM') as month_key,
sum(stock_purchased) as revenue
FROM transactions_table
GROUP BY to_char(date_key, 'YYYY-MM')
),
prev_month_revenue as (
SELECT
month_key, revenue, lag(revenue) over (order by month_key) as
prev_month_revenue
FROM monthly_revenue
)
SELECT month_key,revenue,prev_month_revenue, round(100.0*(revenue-
prev_month_revenue)/prev_month_revenue,1) as revenue_growth
FROM prev_month_revenue
ORDER BY month_key;
The structure of my table is as below:
txn_date DATE,
agent_id NUMBER(12),
supervisor_id NUMBER(12),
stock_purchased NUMBER(15),
stock_sold NUMBER(15),
no_of_txns NUMBER(15),
account_balance NUMBER(15)
I would like to have my output in the format below;
Week-Start | Week-End | Week_Purchases | Previous_Week_Purchases | % Growth
If I can get over the initial hurdle of tracking week-on-week purchases and sales, I can easily attach location information.
The trunc function truncates a date to the specified unit. By default this is the day. But you can also use it to get the start of the previous week/month/quarter/year.
The format iw returns the start of the ISO week. Which is a Monday.
So how does that help you with weeks running Weds-Tues?
Subtract two from your date before passing it to trunc and voila!
with rws as (
select date'2018-07-24'+level dt from dual
connect by level <= 14
)
select * from rws;
DT
25-JUL-2018
26-JUL-2018
27-JUL-2018
28-JUL-2018
29-JUL-2018
30-JUL-2018
31-JUL-2018
01-AUG-2018
02-AUG-2018
03-AUG-2018
04-AUG-2018
05-AUG-2018
06-AUG-2018
07-AUG-2018
with rws as (
select date'2018-07-24'+level dt from dual
connect by level <= 14
)
select trunc ( dt-2, 'iw' ),
to_char ( min ( dt ), 'DY' ) week_start_day,
to_char ( max ( dt ), 'DY' ) week_end_day
from rws
group by trunc ( dt-2, 'iw' )
order by trunc ( dt-2, 'iw' );
TRUNC(DT-2,'IW') WEEK_START_DAY WEEK_END_DAY
23-JUL-2018 WED TUE
30-JUL-2018 WED TUE
Regarding:
I want to be able to compare, say, 3 days worth of the current week's transactions with 3 days worth of the previous week's transactions
I'm not sure what you're asking here. But you can use the windowing clause of analytic functions to get values that fall in a specific offset from the current. For example, the following calculates two running total. The first over the past three days. The second the corresponding three days in the previous week:
with rws as (
select date'2018-07-24'+level dt ,
round ( dbms_random.value( 1, 100 ) ) val
from dual
connect by level <= 10
)
select dt, val,
sum ( val ) over (
order by dt range between 3 preceding and current row
) past_three,
sum ( val ) over (
order by dt range between 10 preceding and 7 preceding
) three_prev_week
from rws
order by dt;
DT VAL PAST_THREE THREE_PREV_WEEK
25-JUL-2018 5 5 <null>
26-JUL-2018 89 94 <null>
27-JUL-2018 34 128 <null>
28-JUL-2018 88 216 <null>
29-JUL-2018 48 259 <null>
30-JUL-2018 25 195 <null>
31-JUL-2018 19 180 <null>
01-AUG-2018 71 163 5
02-AUG-2018 12 127 94
03-AUG-2018 39 141 128

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.

How to get avg from date range?

I have a Date dimenstion with levels: Year, Month, Day. I am need to get average by month for range like this [Date].[2011].[1].[10]:[Date].[2011].[10].[20]
Something along these lines:
AVG(
EXISTS(
[Date].[Month].MEMBERS
,[Date].[2011].[1].[10]:[Date].[2011].[10].[20]
)
)
Or if you want the daily average:
AVG(
[Date].[2011].[1].[10]:[Date].[2011].[10].[20]
)
Or is you want the average by the count of number of days for the range you specified:
DIVIDE(
SUM([Date].[2011].[1].[10]:[Date].[2011].[10].[20])
,EXISTS(
[Date].[Month].MEMBERS
,[Date].[2011].[1].[10]:[Date].[2011].[10].[20]
).count
)