Troubling MDX Query - reporting-services

I have an MDX query I have been struggling with for a while and just can't seem to get it to fly right!! THe pain point is the subquery that is trying to pull in only those jobs that have a status of anythign BUT "Closed" (DIM PROJECT].[Job Status].&[Closed]}. I know/think I'm maybe missing a parentheses somewhere possibly???
MAybe a second set of eyes would help???
SELECT
NON EMPTY
{
[Measures].[Estimate Extended Amount]
,[Measures].[Estimate Line Total]
,[Measures].[Estimate Markup Amount]
} ON COLUMNS
,NON EMPTY
{
[DIM PROJECT].[Client - Division - Product - Component].[Job Component Number].ALLMEMBERS*
[DIM PROJECT].[Component Description].[Component Description].ALLMEMBERS*
[DIM PROJECT].[Client PO Number].[Client PO Number].ALLMEMBERS*
[DIM PROJECT].[Job Status].[Job Status].ALLMEMBERS*
[DIM PROJECT].[Project Start Date].[Project Start Date].ALLMEMBERS*
[DIM PROJECT].[Project End Date].[Project End Date].ALLMEMBERS*
[DIM FUNCTION].[Function Category].[Function Category].ALLMEMBERS*
[DIM ESTIMATE].[Estimate Number].[Estimate Number].ALLMEMBERS*
[DIM ESTIMATE].[Estimate Status].[Estimate Status].ALLMEMBERS
}
DIMENSION PROPERTIES
MEMBER_CAPTION
,MEMBER_UNIQUE_NAME
ON ROWS
FROM
(
SELECT
{[DIM ESTIMATE].[Estimate Status].&[Approved]} ON COLUMNS
FROM (-{[DIM PROJECT].[Job Status].&[Closed]} ON COLUMNS
(
SELECT
StrToSet
(#DIMPROJECTProduct
,CONSTRAINED
) ON COLUMNS
FROM
(
SELECT
StrToSet
(#DIMPROJECTDivision
,CONSTRAINED
) ON COLUMNS
FROM
(
SELECT
StrToSet
(#DIMPROJECTClient
,CONSTRAINED
) ON COLUMNS
FROM [ESTIMATES]
)
)
)
)
WHERE
(
IIF
(
StrToSet
(#DIMPROJECTClient
,CONSTRAINED
).Count
= 1
,StrToSet
(#DIMPROJECTClient
,CONSTRAINED
)
,[DIM PROJECT].[Client].CurrentMember
)
,IIF
(
StrToSet
(#DIMPROJECTDivision
,CONSTRAINED
).Count
= 1
,StrToSet
(#DIMPROJECTDivision
,CONSTRAINED
)
,[DIM PROJECT].[Division].CurrentMember
)
,IIF
(
StrToSet
(#DIMPROJECTProduct
,CONSTRAINED
).Count
= 1
,StrToSet
(#DIMPROJECTProduct
,CONSTRAINED
)
,[DIM PROJECT].[Product].CurrentMember
)
)
CELL PROPERTIES
VALUE
,BACK_COLOR
,FORE_COLOR
,FORMATTED_VALUE
,FORMAT_STRING
,FONT_NAME
,FONT_SIZE
,FONT_FLAGS;

I am not quite sure what you are trying to do, but it seems like you might be over complicating your query a little bit. I think the function you are looking for is EXCEPT:
Except([DIM PROJECT].[Job Status].[All].Children,[DIM PROJECT].[Job Status].&[Closed])
This will give you all job statuses except closed. If you put it in your where clause (ymmv with my simplification) it might read:
SELECT
NON EMPTY
{
[Measures].[Estimate Extended Amount]
,[Measures].[Estimate Line Total]
,[Measures].[Estimate Markup Amount]
} ON COLUMNS
,NON EMPTY
{
[DIM PROJECT].[Client - Division - Product - Component].[Job Component Number].ALLMEMBERS*
[DIM PROJECT].[Component Description].[Component Description].ALLMEMBERS*
[DIM PROJECT].[Client PO Number].[Client PO Number].ALLMEMBERS*
[DIM PROJECT].[Job Status].[Job Status].ALLMEMBERS*
[DIM PROJECT].[Project Start Date].[Project Start Date].ALLMEMBERS*
[DIM PROJECT].[Project End Date].[Project End Date].ALLMEMBERS*
[DIM FUNCTION].[Function Category].[Function Category].ALLMEMBERS*
[DIM ESTIMATE].[Estimate Number].[Estimate Number].ALLMEMBERS*
[DIM ESTIMATE].[Estimate Status].&[Approved]
}
DIMENSION PROPERTIES
MEMBER_CAPTION
,MEMBER_UNIQUE_NAME
ON ROWS
FROM [ESTIMATES]
WHERE
( StrToSet(#DIMPROJECTProduct),
StrToSet(#DIMPROJECTDivision),
StrToSet(#DIMPROJECTClient),
Except([DIM PROJECT].[Job Status].[All].Children,[DIM PROJECT].[Job Status].&[Closed]))
If your parameters happen to be single members you can probably just use StrToMember in the where clause.

Related

MDX Query Taking very long time when executed from SSRS

I have a query that takes very long time when queries from an SSRS Report (25 Minutes).
When I try to execute it from SSMS, I get the following error after 1 minute:
Executing the query ...
Exception of type 'System.OutOfMemoryException' was thrown.
SELECT
NON EMPTY {
[Measures].[Invoice Qty MT - VW Fact Total Sales],
[Measures].[Invoice Value EGPUSD - VW Fact Total Sales]
} ON COLUMNS,
NON EMPTY {
(
[Dim Invoice Date].[Year].[Year].allmembers *
[Dim Company].[Data Area ID].[Data Area ID].allmembers *
[Dim Customer].[Customer Type].[Customer Type].allmembers *
[Dim Invoice Date].[Month Str].[Month Str].allmembers *
[Dim Invoice Date].[Month Eng].[Month Eng].allmembers *
[Dim Customer].[Customer Classification].[Customer Classification].allmembers
*
[Dim Item].[Item Number].[Item Number].allmembers *
[Dim Item].[Item Name].[Item Name].allmembers *
[Dim Customer].[Customer Num].[Customer Num].allmembers *
[Dim Customer].[Customer Name].[Customer Name].allmembers *
[Dim Item].[Factory Packing Group EN].[Factory Packing Group EN].allmembers *
[Dim Item].[Factory Packaging Group ID].[Factory Packaging Group ID].allmembers
)
} DIMENSION PROPERTIES member_caption, member_unique_name ON ROWS
FROM ( SELECT
(
{
[Dim Packing Group].[Packing Group ID].&[1],
[Dim Packing Group].[Packing Group ID].&[2],
[Dim Packing Group].[Packing Group ID].&[3],
[Dim Packing Group].[Packing Group ID].&[4],
[Dim Packing Group].[Packing Group ID].&[5],
[Dim Packing Group].[Packing Group ID].&[6],
[Dim Packing Group].[Packing Group ID].&[7]
}
) ON COLUMNS
FROM [BI_Cube])
WHERE (
[Dim Packing Group].[Packing Group ID].currentmember
) CELL PROPERTIES value, back_color, fore_color, formatted_value,
format_string, font_name, font_size, font_flags
First, the System.OutOfMemory error is a client-side error in SSMS which means the query returned more data than fit in memory. Try closing and reopening SSMS. Also the following query changes will help (specifically reducing the cell properties that are returned to just VALUE).
SELECT { [Measures].[Invoice Qty MT - VW Fact Total Sales], [Measures].[Invoice Value EGPUSD - VW Fact Total Sales] } ON COLUMNS,
NON EMPTY { (
[Dim Invoice Date].[Year].[Year].ALLMEMBERS
* [Dim Invoice Date].[Month Str].[Month Str].ALLMEMBERS
* [Dim Invoice Date].[Month Eng].[Month Eng].ALLMEMBERS
* [Dim Company].[Data Area ID].[Data Area ID].ALLMEMBERS
* [Dim Customer].[Customer Type].[Customer Type].ALLMEMBERS
* [Dim Customer].[Customer Classification].[Customer Classification].ALLMEMBERS
* [Dim Customer].[Customer Num].[Customer Num].ALLMEMBERS
* [Dim Customer].[Customer Name].[Customer Name].ALLMEMBERS
* [Dim Item].[Item Number].[Item Number].ALLMEMBERS
* [Dim Item].[Item Name].[Item Name].ALLMEMBERS
* [Dim Item].[Factory Packing Group EN].[Factory Packing Group EN].ALLMEMBERS
* [Dim Item].[Factory Packaging Group ID].[Factory Packaging Group ID].ALLMEMBERS
) }
DIMENSION PROPERTIES MEMBER_CAPTION ON ROWS
FROM ( SELECT ( { [Dim Packing Group].[Packing Group ID].&[1], [Dim Packing Group].[Packing Group ID].&[2], [Dim Packing Group].[Packing Group ID].&[3], [Dim Packing Group].[Packing Group ID].&[4], [Dim Packing Group].[Packing Group ID].&[5], [Dim Packing Group].[Packing Group ID].&[6], [Dim Packing Group].[Packing Group ID].&[7] } ) ON COLUMNS FROM [BI_Cube]) WHERE ( [Dim Packing Group].[Packing Group ID].CurrentMember )
CELL PROPERTIES VALUE
Putting all attributes from a single dimension together should help performance. Also I trimmed down the CELL PROPERTIES and DIMENSION PROPERTIES to just the ones you likely use in the SSRS report.
The error is self-explanatory. You don't have memory to calculate the huge crossjoin you got there.
Try to remove some of them, filter your data a bit more or use Properties instead of including everything in crossjoins.
User-Defined Member Properties

How to add ORDER to an MDX based parameter

How can I change the following data set query to order by Employee Name
WITH
MEMBER [Measures].[ParameterCaption] AS
[Employee].[Employee Name].CURRENTMEMBER.MEMBER_CAPTION
MEMBER [Measures].[ParameterValue] AS
[Employee].[Employee ID].CURRENTMEMBER.UNIQUENAME
MEMBER [Measures].[ParameterLevel] AS
[Employee].[Employee ID].CURRENTMEMBER.LEVEL.ORDINAL
SELECT
{[Measures].[ParameterCaption]
, [Measures].[ParameterValue]
, [Measures].[ParameterLevel]} ON COLUMNS ,
[Employee].[Employee ID].ALLMEMBERS ON ROWS
FROM ( SELECT ( STRTOSET(#ReportingCurrencyReportingCurrency, CONSTRAINED) ) ON COLUMNS FROM ( SELECT ( STRTOSET(#PROJGROUPProjGroup, CONSTRAINED) ) ON COLUMNS FROM ( SELECT ( STRTOSET(#CompanyCompanyAccounts, CONSTRAINED) ) ON COLUMNS FROM [ACTIVITY])))
You can try adding the ORDER function - although I'll need to test as I'm unsure this will work:
WITH
MEMBER [Measures].[ParameterCaption] AS
[Employee].[Employee Name].CURRENTMEMBER.MEMBER_CAPTION
MEMBER [Measures].[ParameterValue] AS
[Employee].[Employee ID].CURRENTMEMBER.UNIQUENAME
MEMBER [Measures].[ParameterLevel] AS
[Employee].[Employee ID].CURRENTMEMBER.LEVEL.ORDINAL
SELECT
{[Measures].[ParameterCaption]
, [Measures].[ParameterValue]
, [Measures].[ParameterLevel]} ON COLUMNS ,
ORDER(
[Employee].[Employee ID].ALLMEMBERS,
[Measures].[ParameterCaption],
BDESC
)ON ROWS
FROM ( SELECT ( STRTOSET(#ReportingCurrencyReportingCurrency, CONSTRAINED) ) ON COLUMNS FROM ( SELECT ( STRTOSET(#PROJGROUPProjGroup, CONSTRAINED) ) ON COLUMNS FROM ( SELECT ( STRTOSET(#CompanyCompanyAccounts, CONSTRAINED) ) ON COLUMNS FROM [ACTIVITY])))

RANKING Function in DAX or MDX

How can i get result in attached image by DAX or MDX.Both can work for me.
( I will use DAX in Tabular Model and Will use MDX on SSRS part).
Sample Format
I tried below code but it didn't work.
WITH
SET OrderSet AS
Order
(
(
[Dim Product].[Category Name].[Category Name].MEMBERS
,[Dim Product].[Subcategory Name].[Subcategory Name].MEMBERS
,[Dim Product].[Sub Subcategory Name].[Sub Subcategory Name].MEMBERS
,[Dim Product].[Product Name].[Product Name].MEMBERS
)
,[Measures].[Order Quantity]
,BDESC
)
MEMBER [Measures].[RankOrderCount] AS
Rank
(
(
[Dim Product].[Category Name].CurrentMember
,[Dim Product].[Subcategory Name].CurrentMember
,[Dim Product].[Sub Subcategory Name].CurrentMember
,[Dim Product].[Product Name].CurrentMember
)
,OrderSet
)
SELECT
{
[Measures].[Order Quantity]
,[Measures].[RankOrderCount]
} ON 0
,NON EMPTY
{OrderSet} ON 1
FROM [Adventure Works DW2016CTP3];
I don't understand the problem. If I run this:
WITH
SET OrderSet AS
Order
(
(
[Product].[Category].[Category].MEMBERS
,[Product].[Subcategory].[Subcategory].MEMBERS
)
,[Measures].[Order Quantity]
,BDESC
)
MEMBER [Measures].[RankOrderCount] AS
Rank
(
(
[Product].[Category].CurrentMember
,[Product].[Subcategory].CurrentMember
)
,OrderSet
)
SELECT
{
[Measures].[Order Quantity]
,[Measures].[RankOrderCount]
} ON 0
,NON EMPTY
{OrderSet} ON 1
FROM [Adventure Works];
I get this:
This looks like your desired output format - but I did not change the script - so what is the question?
For example:
DEFINE
VAR TableTMP1 =
SELECTCOLUMNS (
DimProductTable,
"Product Name", DimProductTable[Product Name],
"Sub Subcategory Name", RELATED ( SubSubcategoryTable[Sub Subcategory Name] ),
"Subcategory Name", RELATED ( SubcategoryTable[Subcategory Name] ),
"Category Name", RELATED ( CategoryTable[Category Name] )
)
VAR TableTMP2 =
ADDCOLUMNS (
TableTMP1,
"Order Count", CALCULATE ( SUM ( OrderTable[Quantity] ) )
)
EVALUATE
ADDCOLUMNS ( TableTMP2, "Rank", RANKX ( TableTMP2, [Order Count], ASC ) )
ORDER BY [Rank] ASC

MDX How to calculate measure against dimension without displaying members in results

Could someone please help me with the below MDX problem:
I got the dataset like the one below:
With
Set Range1 as {[Date].[Calendar].[Month].&[2008]&[1]
:[Date].[Calendar].[Month].&[2008]&[12]}
Set Range2 as
{[Delivery Date].[Calendar].[Month].&[2008]&[1]:
[Delivery Date].[Calendar].[Month].&[2008]&[12]}
MEMBER measures.A as [Measures].[Internet Order Count] + [Measures].[Reseller Order Count]
select {[Measures].[Internet Order Count],A} on columns,
non empty(
[Sales Territory].[Sales Territory Country].[Sales Territory Country]*
Range1
*Range2
)
having [Date].[Calendar].currentmember.member_caption
= [Delivery Date].[Calendar].currentmember.member_caption
AND A > 100
on rows
from [Adventure Works]
The problem is that results are displayed with [Sales Territory] Dimension - I would like to get the results only displaying months but with measure A also calculated against [Sales Territory].
The results for measure A should looks like:
For example: 1128 for January
The Correct results should looks like:
Thanks
Sorry - was unable to past the code:
WITH MEMBER [Measures].[A] AS
[Measures].[Internet Order Count] + [Measures].[Reseller Order Count]
SELECT
{ [Measures].[Internet Order Count], [Measures].[A] } ON COLUMNS,
[Date].[Calendar].[Month] ON ROWS
FROM (
SELECT { [Measures].[Internet Order Count] } ON COLUMNS,
Filter (
Filter ( [Date].[Calendar].[Month] * [Delivery Date].[Calendar].[Month], [Date].[Calendar].CurrentMember.Name = [Delivery Date].[Calendar].CurrentMember.Name ) * [Sales Territory].[Sales Territory Country].[Sales Territory Country],
[Measures].[Internet Order Count] + [Measures].[Reseller Order Count] > 100
) ON ROWS
FROM [Adventure Works]
)
WHERE [Date].[Calendar Year].[CY 2008]
I've ignored the ranges for now but this is as close as I can get:
WITH
MEMBER measures.c1 AS
[Date].[Calendar].CurrentMember.Member_Caption
MEMBER measures.c2 AS
[Delivery Date].[Calendar].CurrentMember.Member_Caption
MEMBER measures.x AS
IIF
(
measures.c1 = measures.c2
,
[Measures].[Internet Order Count] + [Measures].[Reseller Order Count]
,null
)
SET q AS
Filter
(
[Sales Territory].[Sales Territory Country].[Sales Territory Country]*
[Date].[Calendar].[Month].MEMBERS*
[Delivery Date].[Calendar].[Month].MEMBERS
,
measures.x > 100
)
SELECT
{measures.x} ON 0
,NON EMPTY
Extract
(
q
,[Date].[Calendar]
,[Delivery Date].[Calendar]
) ON 1
FROM [Adventure Works];
EDIT
The following gives two options for the Rows - option A and option B:
WITH
MEMBER measures.c1 AS
[Date].[Calendar].CurrentMember.Member_Caption
MEMBER measures.c2 AS
[Delivery Date].[Calendar].CurrentMember.Member_Caption
MEMBER measures.x AS
IIF
(
measures.c1 = measures.c2
,
[Measures].[Internet Order Count] + [Measures].[Reseller Order Count]
,null
)
SET q AS
Filter
(
[Sales Territory].[Sales Territory Country].[Sales Territory Country]*
[Date].[Calendar].[Month].&[2008]&[1]*
[Delivery Date].[Calendar].[Month].MEMBERS
,
measures.x > 100
)
SELECT
{measures.x} ON 0
//<<<<<Option A.try just this and sum the cells ....1128
,q
//<<<<<Option B.try just this and sum the cells ....1221
//,Extract
// (
// q
// ,[Date].[Calendar]
// ,[Delivery Date].[Calendar]
// )
ON 1
FROM [Adventure Works];
EDIT 2
This gives the correct answer - be mean of me not to reference the real author: https://social.msdn.microsoft.com/Forums/en-US/be750f75-0e39-41b8-9578-9dceb58a5865/strange-context-aware-behaviour-of-adventure-works-script?forum=sqlanalysisservices
WITH
MEMBER measures.c1 AS
[Date].[Calendar].CurrentMember.Member_Caption
MEMBER measures.c2 AS
[Delivery Date].[Calendar].CurrentMember.Member_Caption
MEMBER measures.[Calendar Month] AS
measures.c1
MEMBER measures.[Delivery Month] AS
measures.c2
MEMBER measures.x AS
IIF
(
measures.c1 = measures.c2
,
[Measures].[Internet Order Count] + [Measures].[Reseller Order Count]
,NULL
)
SELECT
{
measures.[Calendar Month]
,measures.[Delivery Month]
,measures.x
} ON COLUMNS
FROM [Adventure Works]
WHERE
{
NonEmpty
(
[Sales Territory].[Sales Territory].[Country].MEMBERS*
[Date].[Calendar].[Month].&[2008]&[1]*
[Delivery Date].[Calendar].[Month].MEMBERS
,measures.x
)
}
-
{
Filter
(
NonEmpty
(
[Sales Territory].[Sales Territory].[Country].MEMBERS*
[Date].[Calendar].[Month].&[2008]&[1]*
[Delivery Date].[Calendar].[Month].MEMBERS
,measures.x
)
,
measures.x < 100
)
};
You can filter with sales territory, by doing the following instead of your current from [Adventure Works]
from (
select {[Sales Territory].[Sales Territory Country].[Sales Territory Country]} on columns
from [Adventure Works]
)
Having said that, you can then remove the sales territory from here.. and just have Range1 * Range2
non empty(
[Sales Territory].[Sales Territory Country].[Sales Territory Country]
Range1
*Range2
)
You can then continue to filter, using the MDX Filter function
from (
select {[Sales Territory].[Sales Territory Country].[Sales Territory Country]} on columns
from
(
select {
FILTER (
[Date].[Calendar].MEMBERS
,[Date].[Calendar].currentmember.member_caption = [Delivery Date].[Calendar].currentmember.member_caption and A > 100
)
} on columns
[Adventure Works]
)
)
If you don't want to see [Sales Territory].[Sales Territory Country].[Sales Territory Country] in the final SELECT, you can use EXISTS clause in MDX
With
Set Range1 as {[Date].[Calendar].[Month].&[2008]&[1]
:[Date].[Calendar].[Month].&[2008]&[12]}
Set Range2 as
{[Delivery Date].[Calendar].[Month].&[2008]&[1]:
[Delivery Date].[Calendar].[Month].&[2008]&[12]}
MEMBER measures.A as [Measures].[Internet Order Count] + [Measures].[Reseller Order Count]
select {[Measures].[Internet Order Count],A} on columns,
non empty filter((
exists({Range1
*Range2}, [Sales Territory].[Sales Territory Country].[Sales Territory Country]
)), measures.A > 100)
having [Date].[Calendar].currentmember.member_caption
= [Delivery Date].[Calendar].currentmember.member_caption

How to Order amount by multiple dimensions in MDX?

In my Cube,I have following Measures,Dimensions.
**Measure:**
Amount
**From Customer dimension:**
Busines Unit Number
Business Unit Description
Cust Number
Cust Name
**From Bucket dimension:**
Bucket
I want Amount to be ordered by all these dimensions/attributes.
What I tried in MDX so far is,
SELECT
NON EMPTY {
[Measures].[Amount]
} ON COLUMNS,
NON EMPTY { (
ORDER(
(
[Dim Customer].[BU].[BU].MEMBERS*
[Dim Customer].[BU Description].[BU Description].MEMBERS*
[Dim Customer].[Cust No].[Cust No].ALLMEMBERS*
[Dim Address].[Customer Name].[Customer Name].ALLMEMBERS
),
[Measures].[Amount],
BDESC
)
*
[Bucket Dim].[Bucket].[Bucket].ALLMEMBERS
) } ON ROWS
FROM [Cube]
Still I am not getting proper order as I want & also it is taking a too much time to execute.
You can nest ORDER functions to get multiple order by criteria.
The outer order is applied first - a little counter-intuitive.
The following will be ordered by the value of cust no, then by the caption of BU then by [Measures].[Amount]
SELECT
NON EMPTY
{[Measures].[Amount]} ON COLUMNS
,NON EMPTY
{
Order
(
Order
(
Order
(
[Dim Customer].[BU].[BU].MEMBERS*
[Dim Customer].[BU Description].[BU Description].MEMBERS*
[Dim Customer].[Cust No].[Cust No].ALLMEMBERS*
[Dim Address].[Customer Name].[Customer Name].ALLMEMBERS
,[Measures].[Amount]
,BDESC
)
,[Dim Customer].[BU].CurrentMember.Member_Caption
,BDESC
)
,[Dim Customer].[Cust No].CurrentMember.MemberValue
,BDESC
)
*
[Bucket Dim].[Bucket].[Bucket].ALLMEMBERS
} ON ROWS
FROM [Cube];