How to extract month-year from date from MDX Query - sql

I need to filter data from Cube using Date without day inclusion.
Currently I am using following MDX query, that is fetching measures data starting from 1st day of the year and ending on the last day.
But, I only want to have Month-Year in date time at rows rather than DateTime with all days. ( Here my field for date is : [Period].[TransportDate] )
Following is the MDX Query.
SELECT
NON EMPTY
{
[Measures].[ConsignmentCount]
, [Measures].[CBM]
, [Measures].[LDM]
, [Measures].[Weight]
, [Measures].[Amount] } ON COLUMNS,
NON EMPTY
{ [Period].[TransportDate].Children } ON ROWS
FROM
(
SELECT
(
{ [Period].[YearAndMonth].[ConsignmentYear].&[2014]
, [Period].[YearAndMonth].[ConsignmentYear].&[2015] }
) ON COLUMNS
FROM [RebellOlap]
)
Above query fetching all records starting from 1st day till the last day of 2015. See attached image ( allRecords )
But I want somehow in following manner ( Required Data Set )
I want single column instead of Month and year. So
final data set should be
( e.g Date ( 07-2015 ), Amount,CBM, LDM, Num,. Consignments )
I know there's a way to extract only month and year from the whole date. But that works only for single date. What I want to have all dates must be filtered with the inclusion of month and Year and data should also corresponds to those dates accordingly. See above expected filtered data set.
Edit
WITH MEMBER [YearMo] AS
[Period].[ConsignmentYear].Currentmember.Name
+ "-" +
[Period].[ConsignmentMonth].Currentmember.Name
SELECT
NON EMPTY
{
[Measures].[ConsignmentCount]
, [Measures].[CBM]
, [Measures].[LDM]
, [Measures].[Weight]
, [Measures].[Amount]
} ON COLUMNS ,
NON EMPTY
(
{
[Period].[YearAndMonth].[ConsignmentMonth]
}
) ON ROWS
FROM
(
SELECT
(
{
[Period].[YearAndMonth].[ConsignmentYear].&[2014]
, [Period].[YearAndMonth].[ConsignmentYear].&[2015]
}
) ON COLUMNS
FROM [RebellOlap]
)
above produces result but without Year.
I want somehow to have year with month on the same columns.
so 01 would becomd 01-2014.
Could you help me
Results without concatenation

Either you have to create a new field as 'YYYY-mm' in the dimension view (cube design-sql view) or you can concatenate the year & month dimension attributes (Example below).
Example Code:
WITH MEMBER [YearMo] AS
[Period].[Monthly].Currentmember.Name
+ "-" + [Period].[YearAndMonth].Currentmember.Name
SELECT
NON EMPTY {[Measures].[ConsignmentCount], [Measures].[CBM], [Measures].[LDM], [Measures].[Weight], [Measures].[Amount]} ON COLUMNS
, NON EMPTY ( { [Period].[Monthly].[Year] } , { [Period].[YearAndMonth].[ConsignmentMonth] } ) ON ROWS
FROM
(
SELECT ( { [Period].[YearAndMonth].[ConsignmentYear].&[2014], [Period].[YearAndMonth].[ConsignmentYear].&[2015] } ) ON COLUMNS
FROM [RebellOlap]
)

Maybe try hosting the calculated member in a different hierarchy. I have guessed this [Forwarder].[Forwarder].[All] and you will need to adjust to a hierarchy that exists in your cube:
WITH MEMBER [Forwarder].[Forwarder].[All].[YearMo] AS
[Period].[Year].Currentmember.Name
+ "-" +
[Period].[Month].Currentmember.Name
SELECT
NON EMPTY
{
[Measures].[ConsignmentCount]
, [Measures].[CBM]
, [Measures].[LDM]
, [Measures].[Weight]
, [Measures].[Amount]
} ON COLUMNS ,
NON EMPTY
[Period].[Year].[Year]
*[Period].[Month].[Month]
*[Forwarder].[Forwarder].[All].[YearMo]
ON ROWS
FROM
(
SELECT
(
{
[Period].[YearAndMonth].[ConsignmentYear].&[2014]
, [Period].[YearAndMonth].[ConsignmentYear].&[2015]
}
) ON COLUMNS
FROM [RebellOlap]
)
Or if the above produces an error then you may need to create a measure first:
WITH
MEMBER [Measures].[YearMoString] AS
[Period].[Year].Currentmember.Name
+ "-" +
[Period].[Month].Currentmember.Name
MEMBER [Forwarder].[Forwarder].[All].[YearMo] AS
(
[Forwarder].[Forwarder].[All]
,[Measures].[YearMoString]
)
SELECT
NON EMPTY
{
[Measures].[ConsignmentCount]
, [Measures].[CBM]
, [Measures].[LDM]
, [Measures].[Weight]
, [Measures].[Amount]
} ON COLUMNS ,
NON EMPTY
[Period].[Year].[Year]
*[Period].[Month].[Month]
*[Forwarder].[Forwarder].[All].[YearMo]
ON ROWS
FROM
(
SELECT
(
{
[Period].[YearAndMonth].[ConsignmentYear].&[2014]
, [Period].[YearAndMonth].[ConsignmentYear].&[2015]
}
) ON COLUMNS
FROM [RebellOlap]
)

Related

MDX: sum over time with range in rows

I have a day level in my time dimension.
I want to output the sum/avg for a selected range of days like in the following statement:
WITH
MEMBER measures.[sum1] AS
Sum([Measures].[Menge_Artikel_Stk])
MEMBER measures.[sum2] AS
Sum
(
[D_Datum].[Datum].[Tag]
,[Measures].[Menge_Artikel_Stk]
)
SELECT
{
[Measures].[stock]
,[Measures].[sum1]
,[Measures].[sum2]
} ON 0
,NON EMPTY
CrossJoin
(
{[D_item].[itemno].[itemno].MEMBERS}
,{
[D_Date].[Date].[day].[30.01.2017] : [D_Date].[Date].[Day].[05.02.2017]
}
) ON 1
FROM [Cube];
My goal is to show the sum/avg along the date-dimension filtered on rows.
Instead of 40/1653 i want sum to display 250 for the sum or 35,7 for the average. (1653 is obviously the sum of the entire day level). I want to add this calculated member to an Excel-Sheet. Thus the time range set is variable.
To get the sum/avg rows across the specific range you can do something like this:
WITH
MEMBER measures.[sum1] AS
Sum([Measures].[Menge_Artikel_Stk])
MEMBER measures.[sum2] AS
Sum
(
[D_Datum].[Datum].[Tag]
,[Measures].[Menge_Artikel_Stk]
)
MEMBER [D_Date].[Date].[All].[DaySum] AS
Sum
(
[D_Date].[Date].[day].[30.01.2017] : [D_Date].[Date].[Day].[05.02.2017]
)
MEMBER [D_Date].[Date].[All].[DayAvg] AS
Avg
(
[D_Date].[Date].[day].[30.01.2017] : [D_Date].[Date].[Day].[05.02.2017]
)
SELECT
{
[Measures].[stock]
,[Measures].[sum1]
,[Measures].[sum2]
} ON 0
,NON EMPTY
CrossJoin
(
{[D_item].[itemno].[itemno].MEMBERS}
,{
{
[D_Date].[Date].[day].[30.01.2017] : [D_Date].[Date].[Day].[05.02.2017]
}
,[D_Date].[Date].[All].[DaySum]
,[D_Date].[Date].[All].[DayAvg]
}
) ON 1
FROM [Cube];
You can use the Axis function to define the current set on your axis:
WITH
MEMBER measures.[sum] AS
Sum(
Axis(1),
[Measures].[Menge_Artikel_Stk]
)
MEMBER measures.[avg] AS
AVG(
Axis(1),
[Measures].[Menge_Artikel_Stk]
)
SELECT
{[Measures].[Menge_Artikel_Stk],[Measures].[sum],[Measures].[avg]} ON 0,
NON EMPTY {[D_Date].[Date].[day].[30.01.2017]:[D_Date].[Date].[Day].[05.02.2017]} ON 1
FROM [Cube];

MDX query optimization while using CrossJoin

I am writing an MDX query in which i am selecting some Measures and while selection i have a where condition in which i am doing a cross join two facts , one is date and another a unique id and i am passing around 2000 unique ids and the query is taking around 20 minutes to execute and give the result.
Please find below query for the same
SELECT {[Measures].[TOTAL1], [Measures].[TOTAL2], [Measures].[TOAL3]} ON COLUMNS,
" + " {TOPCOUNT(FILTER([ID].[Ids].MEMBERS,
[ID].CurrentMember > 0),
5,[Measures].[TOTAL])} " + "ON ROWS
FROM [CHARTS]
WHERE({[Date].&[2015-09-01 00:00:00.0]}*{[NUM].[1],[NUM].[10],"
+ "[NUM].[18],[NUM].[47],[NUM].[52],[NUM].[105],[NUM].[126],[NUM].[392],"
+ "[NUM].[588],[NUM].[656],[NUM].[995],[NUM].[1005],[NUM].[1010],[NUM].[1061]})";
The straight mdx without the string manipulation operators (+) is as follows:
SELECT
{
[Measures].[TOTAL1]
,[Measures].[TOTAL2]
,[Measures].[TOAL3]
} ON COLUMNS
,{
TopCount
(
Filter
(
[ID].[Ids].MEMBERS
,
[ID].CurrentMember > 0
)
,5
,[Measures].[TOTAL]
)
} ON ROWS
FROM [CHARTS]
WHERE
{[Date].&[2015-09-01 00:00:00.0]}
*
{
[NUM].[1]
,[NUM].[10]
,[NUM].[18]
,[NUM].[47]
,[NUM].[52]
,[NUM].[105]
,[NUM].[126]
,[NUM].[392]
,[NUM].[588]
,[NUM].[656]
,[NUM].[995]
,[NUM].[1005]
,[NUM].[1010]
,[NUM].[1061]
};
Can you please tell me the different performance optimization techniques for the same.
TopCount is slow if you use the third ordering parameter - it is better to order the data first and then feed your pre-ordered set into TopCount with just 2 parameters:
WITH
SET [S0] AS
Filter
(
[ID].[Ids].MEMBERS
,
[ID].CurrentMember > 0
)
SET [S1] AS
Order
(
[S0]
,[Measures].[TOTAL]
,BDESC
)
SET [S2] AS
TopCount
(
[S1]
,5
)
SELECT
{
[Measures].[TOTAL1]
,[Measures].[TOTAL2]
,[Measures].[TOAL3]
} ON COLUMNS
,[S2] ON ROWS
FROM [CHARTS]
WHERE
{[Date].&[2015-09-01 00:00:00.0]}
*
{
[NUM].[1]
,[NUM].[10]
,[NUM].[18]
,[NUM].[47]
,[NUM].[52]
,[NUM].[105]
,[NUM].[126]
,[NUM].[392]
,[NUM].[588]
,[NUM].[656]
,[NUM].[995]
,[NUM].[1005]
,[NUM].[1010]
,[NUM].[1061]
};

How can I filter by date and hour dimension while I want explore them?

First things first, my cube's time dimension has been created by me from two separated dimension .
Time dimension with: hour, half hour , ten minutes and minutes fields .
Date dimension with: day, month and year fields
My problem is that, when I want to explore and filter several full days and not full days, results are like if I was only exploring full days.
Let me show you the mdx I use:
select non empty ([Client].[Client].[Client],[Product].[Product].[Product]) on rows,
{[Measures].[Example]} on columns
from [Cube]
where ( {([Date].[Id].&[20131002] ) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2059]) } +{([Date].[Id].&[20130930] : [Date].[Id].&[20131001]) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2359]) } )
That mdx works because there arenĀ“t date or time dimension.
This one doesn't work:
select non empty ([Date].[Date Field].[Date Field]) on rows,
{[Measures].[Example]} on columns
from [Cube]
where ( {([Date].[Id].&[20131002] ) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2059]) } + {([Date].[Id].&[20130930] : [Date].[Id].&[20131001]) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2359]) } )
I have noticed that if I divide the mdx like this:
select non empty ([Date].[Date Field].[Date Field]) on rows,
{[Measures].[Example]} on columns
from [Cube]
where ( {([Date].[Id].&[20131002] ) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2059]) } }
select non empty ([Date].[Date Field].[Date Field]) on rows,
{[Measures].[Example]} on columns
from [Cube]
where ( {{([Date].[Id].&[20130930] : [Date].[Id].&[20131001]) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2359]) }
it works! But I want do it , with one mdx.
If anyone could help me I would be very grateful!!
Regards.
You could try with a subselect:
select non empty (EXISTING [Date].[Date Field].[Date Field]) on rows,
{[Measures].[Example]} on columns
from (select
( {([Date].[Id].&[20131002] ) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2059]) }
+ {([Date].[Id].&[20130930] : [Date].[Id].&[20131001]) *([Time].[Time Field].&[0] : [Time].[Time Field].&[2359]) } )
on columns
from [Cube]
)
By the way, your MDX is illegal (but Analysis Services is tolerant): According to the MDX specification, columns must be specified before rows in the select clause.

Values of dimension with like clause SSAS

i want values of dimension with like clause.. i tried this
WITH
SET CITY
AS
FILTER(
[CITY].[CITY].CHILDREN,
vbamdx!INSTR([CITY].[CITY].CURRENTMEMBER.Name,'In',1 >= 1 )
)
MEMBER [Measures].[Label] AS [CITY].[CITY].CURRENTMEMBER.MEMBER_CAPTION
SELECT {[Measures].[Label]
} ON COLUMNS ,
[CITY].[CITY].ALLMEMBERS ON ROWS
FROM [TEST_Cube]
want All Cities with name containing "In".
You're not using the filtered set you made.
Also, you're naming your set the same as the dimension which might give you trouble.
Try:
WITH
SET FilteredCities AS
FILTER
(
[CITY].[CITY].CHILDREN,
vbamdx!INSTR([CITY].[CITY].CURRENTMEMBER.Name,'In',1 >= 1 )
)
MEMBER [Measures].[Label] AS
[CITY].[CITY].CURRENTMEMBER.MEMBER_CAPTION
SELECT
{
[Measures].[Label]
}
ON COLUMNS ,
FilteredCities //Use the set
ON ROWS
FROM [TEST_Cube]

MDX - TopCount plus 'Other' or 'The Rest'

I have created an MDX query which calculates the TOP 10 ZipCodes (according to my Patient Stay measure) as such:
WITH
MEMBER [Discharge Date].[Y-M-D].[ Aggregation] AS 'AGGREGATE( EXISTING { [Current Month] } )', SOLVE_ORDER = 0
SELECT
NON EMPTY { [Measures].[Patient Stays] }
ON COLUMNS,
TOPCOUNT({ ORDER( HIERARCHIZE( { [Patient].[ByZipcode].[All].CHILDREN } ), ( [Measures].[Patient Stays] ), BDESC ) }, 10)
ON ROWS
FROM [Patient Stay]
WHERE ( [Discharge Date].[Y-M-D].[ Aggregation], [Facility].[ByAffiliation].CURRENTMEMBER, [Facility].[ByRegion].CURRENTMEMBER )
This query is used to populate a PerformancePoint 100% Stacked Bar chart. The client has asked that since this is a !00% based chart, we lump the rest of the zip codes into an "Other" field, such that there should be 11 values: one for each of the top 10, and an eleventh which is a sum of the remaining Zip Codes.
I am an extreme novice to MDX, but this doesn't souund like it should be impossible. Does anyone have any ideas or suggestions?
I'll do my best with untested code, so here goes:
WITH
MEMBER [Discharge Date].[Y-M-D].[ Aggregation] AS 'AGGREGATE( EXISTING { [Current Month] } )', SOLVE_ORDER = 0
SET [Top10ZipCodes] AS
(TOPCOUNT({ ORDER( HIERARCHIZE( { [Patient].[ByZipcode].[All].CHILDREN } ), ( [Measures].[Patient Stays] ), BDESC ) }, 10))
MEMBER [Patient].[ByZipCode].[OtherZipCodes] AS
(AGGREGATE({EXCEPT([Patient].[ByZipCode].Members, [Patient].[ByZipCode].[Top10ZipCodes])}))
SELECT
NON EMPTY { [Measures].[Patient Stays] }
ON COLUMNS,
{[Top10ZipCodes], [Patient].[ByZipCode].[OtherZipCodes]}
ON ROWS
FROM [Patient Stay]
WHERE ( [Discharge Date].[Y-M-D].[ Aggregation], [Facility].[ByAffiliation].CURRENTMEMBER, [Facility].[ByRegion].CURRENTMEMBER )
What this does is creates a set of your top 10 ZIP codes, and then aggregates (different than sum!!!) all the ZIP codes, with the exception of your top 10.
Also, if this is a common set (top 10 ZIP codes), you may want to make a set on the cube, where you can reuse it ad nauseum, without having to change every MDX query you have.
Cheers,
Eric