SSAS MDX Previous Year - Country aggregation problem - ssas

my previous question for SSAS MDX Previous Year - Ignore Filter was solved. Now i have an other problem. I get now the right previous year result for the store but the aggregation on country level is wrong.
My problem was i doesn't get the previous year value for a store because the filter kicked that value:
Store | Turnover Actual | Turnover PrevYear
Hamburg | 100.00 | 120.00
Munich | 140.00 | 130.00
Cologne | 90.00 | 110.00
Berlin | 150.00 | null
I tried then this query from MoazRub:
with
member [Measures].[Turnover PrevYear] as
IIF( IsEmpty([Measures].[Turnover Actual] ),
NULL,
SUM(
([Store Status].[Store Status Type].defaultmember, ParallelPeriod( [Date].[Year - Quarter - Month - Date].[Year],1,[Date].[Year - Quarter - Month - Date].CurrentMember))
, [Measures].[Turnover Actual]
)
)
Select
non empty{[Measures].[Turnover Actual],[Measures].[Turnover PrevYear]}
on Columns,
non empty{[Store].[Store].[Store].members}
on Rows
from [Sales Cube]
where (
[Date].[Year - Quarter - Month - Date].[Month].&[2020]&[1],
[Store Status].[Store Status Type].&[Comparable],
[Store].[Country].[Country].&[GERMANY]
)
I get the right result on the Store-Level:
Store | Turnover Actual | Turnover PrevYear
Hamburg | 100.00 | 120.00
Munich | 140.00 | 130.00
Cologne | 90.00 | 110.00
Berlin | 150.00 | 120.00
On the Country-Level I get a wrong SUM because now a other store "Bremen" which is "Not comparable" at january, 2020 is in the sum included.
TOTAL should be (without Bremen which one is "Not comparable": 460.00
TOTAL "is situation" : 580.00 (includes Bremen)
Query on Country-Level:
with
member [Measures].[Turnover PrevYear] as
IIF( IsEmpty([Measures].[Turnover Actual] ),
NULL,
SUM(
([Store Status].[Store Status Type].defaultmember, ParallelPeriod( [Date].[Year - Quarter - Month - Date].[Year],1,[Date].[Year - Quarter - Month - Date].CurrentMember))
, [Measures].[Turnover Actual]
)
)
Select
non empty{[Measures].[Turnover Actual],[Measures].[Turnover PrevYear]}
on Columns,
non empty{[Store].[Country].[Country].&[GERMANY]}
on Rows
from [Sales Cube]
where (
[Date].[Year - Quarter - Month - Date].[Month].&[2020]&[1],
[Store Status].[Store Status Type].&[Comparable]
)
How can I sum on Country-Level only the comparable stores?

My understanding is that berlin Jan 2019 is a special case. You just want to ignore the filter "[Store Status].[Store Status Type].&[Comparable]" for it once. For all the rest you want the filter to work? If that is the case then use the query below. But Make sure you substitute the correct value for
[Date].[Year - Quarter - Month - Date].CurrentMember="January 2020"
In place of "January 2020" use the caption of
[Date].[Year - Quarter - Month - Date].[Month].&[2020]&[1]
with
member [Measures].[Turnover PrevYear] as
IIF( IsEmpty([Measures].[Turnover Actual] ),
NULL,
case when [Store].[Store].currentmember= "Berlin" and [Date].[Year - Quarter - Month - Date].CurrentMember="January 2020"
then
SUM(
([Store Status].[Store Status Type].defaultmember, ParallelPeriod( [Date].[Year - Quarter - Month - Date].[Year],1,[Date].[Year - Quarter - Month - Date].CurrentMember))
, [Measures].[Turnover Actual]
)
else
SUM(
( ParallelPeriod( [Date].[Year - Quarter - Month - Date].[Year],1,[Date].[Year - Quarter - Month - Date].CurrentMember))
, [Measures].[Turnover Actual]
)
end
)
Select
non empty{[Measures].[Turnover Actual],[Measures].[Turnover PrevYear]}
on Columns,
non empty{[Store].[Store].[Store].members}
on Rows
from [Sales Cube]
where (
[Date].[Year - Quarter - Month - Date].[Month].&[2020]&[1],
[Store Status].[Store Status Type].&[Comparable],
[Store].[Country].[Country].&[GERMANY]
)
based on the excel provided, My understand is it sums up all stores, even those that are not in germany.Based on this understanding, You need to use "Existing" keyword to force evaluation of this expersion in context.Try the query below
with
member [Measures].[Turnover PrevYear] as
IIF( IsEmpty([Measures].[Turnover Actual] ),
NULL,
SUM( existing
([Store Status].[Store Status Type].defaultmember, ParallelPeriod( [Date].[Year - Quarter - Month - Date].[Year],1,[Date].[Year - Quarter - Month - Date].CurrentMember))
, [Measures].[Turnover Actual]
)
)
Select
non empty{[Measures].[Turnover Actual],[Measures].[Turnover PrevYear]}
on Columns,
non empty{[Store].[Country].[Country].&[GERMANY]}
on Rows
from [Sales Cube]
where (
[Date].[Year - Quarter - Month - Date].[Month].&[2020]&[1],
[Store Status].[Store Status Type].&[Comparable]
)

Related

Select Fiscal day,week,month in Biqquery

My Financial year starts from September.
I need to select Fiscal day number, Fiscal week number, Fiscal Month number, Fiscal Quarter number, Fiscal Quarter Name
I am getting date range from below query :
select date_sub(boms, interval 0 day) as start_date
from unnest(generate_date_array('2020-01-01','2050-12-31', interval 1 day)) boms
Example :
2020-01-01
2020-01-02
2020-01-03
.....
.....
2025-12-31
The output i need to get :
For Example for the date : 11-Feb-2020
Output:
FISCAL_DAY_OF_YEAR_NUMBER- 162
FISCAL_WEEK_OF_YEAR_NUMBER- 24
FISCAL_MONTH_NUMBER - 6
FISCAL_QUARTER_NUMBER - 2
FISCAL_QUARTER_NAME - Third

How to display Current & Previous Month Name along with Total of Current Revenue per month & Total of Previous Revenue per month through SQL Query?

I have the following tables:
[Revenue Raw Data] consisting of Month_ID,Revenue
and it has the following sample data:
Month_ID
128
124
123
122
126
120
Revenue
1768077
1767617
1734230
1687976
1686309
yt_Calendar_lookup consisting of Month_ID,Month_No,Month_Name
and it has the following sample data:
Month_No
1
2
3
4
5
6
7
8
9
10
11
12
Month_ID
120
121
122
123
124
125
126
127
128
129
130
131
Month_Name
January
February
March
April
May
June
July
August
September
October
November
December
What I am trying to achieve is to display the results for the following 5 columns:
Display Current Month as the first column from the table yt_Calendar_lookup
Display Total Revenue for the Current Month as the second column from the table [Revenue Raw Data]
Display Previous Month as the third column from the table yt_Calendar_lookup
Display Total Revenue for the Previous Month as the fourth column from the table [Revenue Raw Data]
Display Revenue difference between Current Month and Previous Month as the fifth column from the table [Revenue Raw Data]
Initially, this is what I have tried:
SELECT
A.[Total Revenue for Current Month]
, B.[Total Revenue for Previous Month]
, A.[Total Revenue for current Month] - B.[Total Revenue for previous Month] AS 'Revenue Difference between current Month and previous Month'
FROM (
SELECT SUM(CAST(Revenue AS BIGINT)) AS 'Total Revenue for Current Month'
FROM [Revenue Raw Data]
WHERE Month_ID IN (SELECT MAX(Month_ID) FROM [Revenue Raw Data])
) A, (
SELECT SUM(CAST(Revenue AS BIGINT)) AS 'Total Revenue for Previous Month'
FROM [Revenue Raw Data]
WHERE Month_ID IN (SELECT MAX(Month_ID) - 1 FROM [Revenue Raw Data])
) B
With the query above, I could successfully display the following 3 columns:
Total Revenue for Current Month, Total Revenue for Previous Month, Revenue Difference between Current Month and Previous Month
And this is the result I have received:
Total Revenue for Current Month Total Revenue for Previous Month
21221564 19973825
Revenue Difference between current Month and previous Month
1247739
With the next query, I was trying to display the following 5 columns:
Current Month, Total Revenue for Current Month, Previous Month, Total Revenue for Previous Month, Revenue Difference between Current Month and Previous Month
This is what I have tried:
SELECT A.[Current Month],
A.[Total Revenue for Current Month],
B.[Previous Month],
B.[Total Revenue for Previous Month],
A.[Total Revenue for current Month] - B.[Total Revenue for previous Month]
AS 'Revenue Difference between current Month and previous Month'
FROM
(SELECT Month_Name
AS 'Current Month',
SUM(CAST(Revenue AS BIGINT))
AS 'Total Revenue for Current Month'
FROM [Revenue Raw Data], yt_Calendar_lookup
WHERE [Revenue Raw Data].Month_ID = yt_Calendar_lookup.Month_ID
AND [Revenue Raw Data].Month_ID IN
(SELECT MAX(Month_ID) FROM [Revenue Raw Data])
) A,
(SELECT Month_Name
AS 'Previous Month',
SUM(CAST(Revenue AS BIGINT))
AS 'Total Revenue for Previous Month'
FROM [Revenue Raw Data], yt_Calendar_lookup
WHERE [Revenue Raw Data].Month_ID = yt_Calendar_lookup.Month_ID
AND [Revenue Raw Data].Month_ID IN
(SELECT MAX(Month_ID) - 1 FROM [Revenue Raw Data])
) B
I received the following error message:
Column 'yt_Calendar_lookup.Month_Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I even tried by adding GROUP BY A.Month_Name,B.Month_Name, and even after that I am receiving the same error message.
I am still trying to figure out on where I am making the mistake for this particular query.
Solution for this particular issue will be highly appreciated.
You just had to add GROUP BY Month_Name to the 2 sub-queries.
SELECT
C.[Current Month],
C.[Total Revenue for Current Month],
P.[Previous Month],
P.[Total Revenue for Previous Month],
C.[Total Revenue for current Month] - P.[Total Revenue for previous Month]
AS [Revenue Difference between current Month and previous Month]
FROM
(
SELECT Month_Name AS [Current Month],
SUM(CAST(Revenue AS BIGINT)) AS [Total Revenue for Current Month]
FROM [Revenue Raw Data], yt_Calendar_lookup
WHERE [Revenue Raw Data].Month_ID = yt_Calendar_lookup.Month_ID
AND [Revenue Raw Data].Month_ID IN (
SELECT MAX(Month_ID)
FROM [Revenue Raw Data])
GROUP BY Month_Name
) C
CROSS JOIN
(
SELECT Month_Name AS [Previous Month],
SUM(CAST(Revenue AS BIGINT)) AS [Total Revenue for Previous Month]
FROM [Revenue Raw Data], yt_Calendar_lookup
WHERE [Revenue Raw Data].Month_ID = yt_Calendar_lookup.Month_ID
AND [Revenue Raw Data].Month_ID IN (
SELECT MAX(Month_ID) - 1
FROM [Revenue Raw Data])
GROUP BY Month_Name
) P;
But this can also be calculated via conditional aggregation.
WITH CTE_MONTHS AS (
SELECT TOP 2
Month_ID
, ROW_NUMBER() OVER (ORDER BY Month_ID DESC) AS rn
FROM [Revenue Raw Data]
GROUP BY Month_ID
ORDER BY Month_ID DESC
)
SELECT
Month1 AS [Current Month]
, Revenue1 AS [Total Revenue for Current Month]
, Month2 AS [Previous Month]
, Revenue2 AS [Total Revenue for Previous Month]
, Revenue1 - Revenue2 AS [Revenue Difference between current Month and previous Month]
FROM
(
SELECT
MAX(CASE WHEN m.rn = 1 THEN c.Month_Name END) AS Month1
, MAX(CASE WHEN m.rn = 2 THEN c.Month_Name END) AS Month2
, SUM(CASE WHEN m.rn = 1 THEN CAST(r.Revenue AS BIGINT) END) AS Revenue1
, SUM(CASE WHEN m.rn = 2 THEN CAST(r.Revenue AS BIGINT) END) AS Revenue2
FROM [Revenue Raw Data] r
JOIN CTE_MONTHS m ON m.Month_ID = r.Month_ID
LEFT JOIN yt_Calendar_lookup c ON c.Month_ID = r.Month_ID
) q;
I finally managed to solve the problem.
As mentioned by one of the StackOverflow user, that all I had to add was GROUP BY Month_Name on both the sub-queries.
This is what I have done:
SELECT A.[Current Month], A.[Total Revenue for Current Month], B.[Previous Month], B.[Total Revenue for Previous Month],
A.[Total Revenue for current Month] - B.[Total Revenue for previous Month] AS 'Revenue Difference between current Month and previous Month'
FROM
(SELECT Month_Name AS 'Current Month', SUM(CAST(Revenue AS BIGINT)) AS 'Total Revenue for Current Month'
FROM [Revenue Raw Data], yt_Calendar_lookup
WHERE [Revenue Raw Data].Month_ID = yt_Calendar_lookup.Month_ID
AND [Revenue Raw Data].Month_ID IN (SELECT MAX(Month_ID) FROM [Revenue Raw Data])
GROUP BY Month_Name
) A,
(SELECT Month_Name AS 'Previous Month', SUM(CAST(Revenue AS BIGINT)) AS 'Total Revenue for Previous Month'
FROM [Revenue Raw Data], yt_Calendar_lookup
WHERE [Revenue Raw Data].Month_ID = yt_Calendar_lookup.Month_ID
AND [Revenue Raw Data].Month_ID IN (SELECT MAX(Month_ID) - 1 FROM [Revenue Raw Data])
GROUP BY Month_Name
) B
And it works perfectly.

check whether values lies between or not in SQL

These are my 2 tables
table 2:
date_val
yr_num
yr_wk_num
day_wk_num
yr_wk_nm
day
mo_num
20200808
2020
32
6
202032
Saturday
08
20200809
2020
32
7
202032
Sunday
08
20200810
2020
33
1
202033
Monday
08
20200811
2020
33
2
202033
Tuesday
08
20200812
2020
33
3
202033
Wednesday
08
table1:
sku_id
dateval
sales
ab124
20210603
10
ab124
20210502
20
ab123
20210606
30
Need to check sales is with in + or - 30% of 2 month avg sales
with CTE
as
(
select * from table1 where dateval >= dateadd(mm, -2, dateval)
)
select dateval, sum(sales) as [Total Sales], avg(sales) as [Average Sales] from CTE group by dateval order by 1
I tried below also...
with CTE
as
(
select * from table1 t1 left join table2 t2 on t1.dateval = t2.date_val where t2.date_val >= dateadd(mm, -2, t1.dateval)
)
select dateval,sum(sales) as [Total Sales], avg(sales) as [Average Sales] from CTE group by dateval order by 1
here am doing filtering within table1 but i need to use table 2 to get filtered for past two months and get avg sales.
Next, i need to do +30% to that result avg and -30% result avg and check whether my sales is withn avg sales( avg30% above or below) or not if yes '1' if not '0'
For Ex:
Historic 2 month avg sales 100.
(+30% of avg sales is 130)
(-30% of avg sales is 70)
if sales is 120. i need to check 120 lies between 70 to 130.
please suggest me how to achieve

MDX: Top X by two groupings and Top Y (X>Y) by one of the two groups

I am trying to write a query that shows TOP 4 Internet Sales Amount based on year and product. And, at the same time, I am trying to show TOP 1 Reseller Sales Amount based on year only.
Year Product Internet Sales Amount Reseller Sales Amount
CY 2015 Road-150 Red, 48 $153,215 $25,021
CY 2015 Road-150 Red, 68 $101,215 $25,021
CY 2015 Road-150 Red, 22 $93,215 $25,021
CY 2015 Road-250 Red, 52 $90,215 $25,021
CY 2014 Road-150 Red, 100 $202,215 $60,021
CY 2014 Road-220 Black, 90 $180,101 $60,021
CY 2014 Road-65 Blue, 28 $139,465 $60,021
CY 2014 Road-86 Red, 33 $100,001 $60,021
I wrote a following query to achieve the Top 4 Internet Sales Amount by Year and Product, but couldn't figure out how to add the next measure to the resultset.
WITH
SET [TopSalesbyYearAndProd] AS
Generate
(
[Date].[Calendar Year].[Calendar Year].MEMBERS
,TopCount
(
[Date].[Calendar Year].CurrentMember
*
[Product].[Product].[Product].MEMBERS
,4
,[Measures].[Internet Sales Amount]
)
)
SELECT
{[Measures].[Internet Sales Amount]} ON 0
,NON EMPTY
{[TopSalesbyYearAndProd]} ON 1
FROM [Adventure Works];
This seems to work - there is probably a much more elegant way but I've not found it:
WITH
SET [TopSalesbyYearAndProd] AS
Generate
(
[Date].[Calendar Year].[Calendar Year].MEMBERS
,TopCount
(
[Date].[Calendar Year].CurrentMember
*
[Product].[Product].[Product].MEMBERS
,4
,[Measures].[Internet Sales Amount]
)
)
MEMBER [Measures].[TopResellerAmount] AS
(
Generate
(
{[Date].[Calendar Year].CurrentMember}
,TopCount
(
[Date].[Calendar Year].CurrentMember
*
[Product].[Product].[Product].MEMBERS
,1
,[Measures].[Reseller Sales Amount]
)
).Item(0).Item(1)
,[Measures].[Reseller Sales Amount]
)
SELECT
{
[Measures].[Internet Sales Amount]
,[Measures].[TopResellerAmount]
} ON 0
,NON EMPTY
{[TopSalesbyYearAndProd]} ON 1
FROM [Adventure Works];

Sum of sales by Quarter

How can i use SQL and SUM monthly data (quarter view)? I will not use Stored Procedures etc.
Current data:
ID | Sales
201601 | 5
201602 | 15
201603 | 5
201604 | 20
201605 | 8
201606 | 2
...
My ID column is like yyyymm
What I want is:
Quarter | Sales
Q1 | 25
Q2 | 30
....
You can try a query like below
SELECT
LEFT(ID,4) Year,
'Q'+ CAST((CAST(RIGHT(ID,2) AS INT)-1 )/3 +1 AS varchar) Quarter,
SUM(Sales) Sales
FROM
Yourtable
GROUP BY
LEFT(ID,4),
'Q'+ CAST((CAST(RIGHT(ID,2) AS INT) -1 )/3 +1 AS varchar)
order by year
SQL demo link
You can use DATEPART and QUARTER to get the quarter of a DATETIME. You just need to build the DATETIME using DATEFROMPARTS and parsing your ID column.
The CONCAT just adds 'Q' to the period number.
SELECT LEFT(id,4) [Year],
CONCAT('Q',DATEPART(QUARTER, DATEFROMPARTS(LEFT(id,4), RIGHT(id, 2), 1))) [Quarter],
SUM(Sales) [Sales]
FROM yourtable
GROUP BY LEFT(id,4), DATEPART(q, DATEFROMPARTS(LEFT(id,4), RIGHT(id, 2), 1))
ORDER BY [Year], [Quarter]