MDX crossjoin only where members are equal - ssas

Is it possible to cross join and return only where two members are equal? For example the following query against the Adventure Works in SSAS 2012
select [Measures].[Reseller Sales Amount] on 0
,topcount(([Ship Date].[Date].Children,[Delivery Date].[Date].Children),5) on 1
from [Adventure Works]
would return the following values
Reseller Sales Amount
January 1, 2005 January 1, 2005 (null)
January 1, 2005 January 2, 2005 (null)
January 1, 2005 January 3, 2005 (null)
January 1, 2005 January 4, 2005 (null)
January 1, 2005 January 5, 2005 (null)
What I would like as the result is the following
Reseller Sales Amount
January 1, 2005 January 1, 2005 (null)
January 2, 2005 January 2, 2005 (null)
January 3, 2005 January 3, 2005 (null)
January 4, 2005 January 4, 2005 (null)
January 5, 2005 January 5, 2005 (null)
Can I get a result such as the following using an MDX query with or without using a crossjoin?

This should work for you. Basically I create a Boolean style calculated member, and then include that member in the TOPCOUNT function.
I hope it helps.
Ash
WITH MEMBER [Measures].[MatchingDates] AS
IIF([Ship Date].[Date].MEMBERVALUE = [Delivery Date].[Date].MEMBERVALUE,1,0)
SELECT
[Measures].[Reseller Sales Amount] ON 0
, TOPCOUNT({[Ship Date].[Date].[Date].MEMBERS * [Delivery Date].[Date].[Date].MEMBERS},5,[Measures].[MatchingDates]) ON 1
FROM
[Adventure Works]

Related

Identify overlap percent of IDs between 2 dates in same table

I have a table of names with two different dates. I want to know the count of names that are occurring between the two dates and the overlap percentage.
This is the output format that is desired. I am not looking for dates in between. I am looking for records that are in July 05 and also in August 10. Overlap percentage for each id would be - count of records in July 5 and also August 10/count of records on July 5.(Actual table has dates in date datatype).
Overlap % will always be less than or equal to 100 since count of records existing on July 5 as well as August 10 will always be <=count of records on July 5.
id
Count on July 05
Count of IDs from July 05 included in August 10
% overlap
ABC
BCD
CDE
DEF
EFG
Rough version of the input table
id
type
Group
date
ABC
Mobile
1
July 5
BCD
Mobile
1
July 5
ABC
Desktop
1
August 10
CDE
Mobile
2
July 5
BCD
Mobile
2
August 10
As I understood from your comments, the overlap will be the minimum count value of the two dates, i.e. for ABC if we have 6 in July and 2 in August the overlap will be 2, and if we have 3 in July and 5 in August the overlap will be 3.
If that is the case then you may use the following query tested on MS SQL Server 2019:
SELECT t.id, t.[Count on July 05],
CASE
WHEN t.[Count on July 05]<= t.[Count of August 10] THEN t.[Count on July 05]
WHEN t.[Count on July 05]> t.[Count of August 10] THEN t.[Count of August 10]
END AS [Count of IDs from July 05 included in August 10],
CASE
WHEN t.[Count on July 05]<= t.[Count of August 10] THEN CAST(t.[Count on July 05]*1.00/t.[Count on July 05] * 100 AS DECIMAL(18, 2))
WHEN t.[Count on July 05]> t.[Count of August 10] THEN CAST(t.[Count of August 10]*1.00/t.[Count on July 05] * 100 AS DECIMAL(18, 2))
END AS [% overlap]
FROM(
SELECT id,
COUNT(CASE WHEN [tdate] IN ('July 5') THEN 1 END) as [Count on July 05],
COUNT(CASE WHEN [tdate] IN ('August 10') THEN 1 END) as [Count of August 10]
FROM [Tbl]
GROUP BY id) t
I hope that is what you are looking for.

Calculating percentage between consecutive rows based on an ID in SQL?

I'm trying to calculate and find the largest percentage changes between dates based on an indicator_id
year indicator_id value
-------------------------- --------------- -------
January 1, 1999, 12:00 AM 1 1.99
January 1, 2000, 12:00 AM 1 1.76
January 1, 2001, 12:00 AM 2 3.37
January 1, 2006, 12:00 AM 2 4.59
The output I'm trying to get is
year indicator_id value % change
-------------------------- --------------- ------- ---------
January 1, 1999, 12:00 AM 1 1.99 0%
January 1, 2000, 12:00 AM 1 1.76 ?
January 1, 2001, 12:00 AM 2 3.37 0%
January 1, 2006, 12:00 AM 2 4.59 ?
Please help
You want lag() and some arithmetic:
select t.*,
(1 - value / nullif(lag(value) over (partition by indicator_id order by year), 0)) as ratio
from t;
Note: This returns a ratio between 0 and 1. You can multiple by 100, if you want a percentage.
Also, the first result is NULL, which makes more sense to me than 0. If you really want 0, you can use the 3 argument form of lag(): lag(value, 1, value).

sql server sum aggregate functions

suppose I have this record
empcode net year month
602256 3479.97 2014 1
602256 33125.98 2014 1
602256 5247.11 2014 2
602256 7698.39 2014 2
602256 2941.46 2013 3
602256 5515.57 2014 3
602256 5758.68 2014 3
602256 4966.89 2013 4
602256 4984.06 2013 4
602256 5951.63 2014 4
602256 19861.04 2014 4
what i want to happen is that i want to sum the net with the same year and month hope you can help me thank you in advance.
You should use the GROUP BY clause:
SELECT SUM(net) FROM table GROUP BY [year],[month]
Its very simple by Group By cluase. Also whatever you given in group by clause , you can define in select like below, which gives better idea for calculation.
SELECT year, month, SUM(net) FROM table GROUP BY [year],[month]

Sum of Previous Yr

I have a simple query which does the below:
SELECT
B.WEEK_DT WEEK_DT,
SUM(A.PROFIT) PROFIT
FROM
CUSTOMERS A
INNER JOIN WEEK_TABLE B
ON A.WEEK_ID = B.WEEK_ID
Now, I want to extend this query to get Sum of profit for all of yr 2013. That means, the above data gives me value at weekly level and i also want a separate column which give me 2013_Profit, summing up all weeks of previous yr.
week_dt is in the format of mm-dd-yyyy
also, we have an offset in the week table, if that helps:
- WK_OFFSET WK_DT
-13 February 22, 2014
-12 March 1, 2014
-11 March 8, 2014
-10 March 15, 2014
-9 March 22, 2014
-8 March 29, 2014
-7 April 5, 2014
-6 April 12, 2014
-5 April 19, 2014
-4 April 26, 2014
-3 May 3, 2014
-2 May 10, 2014
-1 May 17, 2014
Please let me know how i can get another column for each customer which gives a sum previous yr profits.
Some thing like the below:
Customer Curr_WK_Profit Prev_YR_Profit
AAA 10 520
BBB 20 1040
CCC 30 1560

MDX: Aggregates over a set

What I am trying to achieves looks very simple, yet I cannot make it work.
My facts are orders which have a date and I have a typical time dimension with the 'Month" and 'Year' levels.
I would like to get an output which lists the number of orders for the last 6 months and the total, like this:
Oct 2009 20
Nov 2009 30
Dec 2009 25
Jan 2009 15
Feb 2010 45
Mar 2010 5
Total 140
I can create the set with the members Oct 2009 until Mar 2010 and I manage to get this part of my desired output:
Oct 2009 20
Nov 2009 30
Dec 2009 25
Jan 2009 15
Feb 2010 45
Mar 2010 5
Just I fail to get the total line.
You can achieve this by adding the ALL member to the set and then wrapping it all in the VisualTotals() function
SELECT
... on COLUMNS,
VISUALTOTALS (
{[Month].[Month].[Oct 2009]:[Month].[Month].[Mar 2010]
, [Month].[Month].[All] }
) ON ROWS
FROM <cube>
here is one possible solution for Adventure Works DW Demo Cube. The query selects the last 6 Order Counts and add a sum on the date dimension:
WITH MEMBER [Date].[Calendar].[Last 6 Mth Order Count] AS
aggregate(
ClosingPeriod([Date].[Calendar].[Month], [Date].[Calendar].[All Periods]).Lag(6)
: ClosingPeriod([Date].[Calendar].[Month], [Date].[Calendar].[All Periods])
)
SELECT {[Measures].[Order Count]} ON COLUMNS
, {ClosingPeriod([Date].[Calendar].[Month], [Date].[Calendar].[All Periods]).Lag(6)
: ClosingPeriod([Date].[Calendar].[Month], [Date].[Calendar].[All Periods])
,[Date].[Calendar].[Last 6 Mth Order Count]}
ON ROWS
FROM [Adventure Works]