Adding a debugging col/row in MDX - ssas

Is it possible to add a manual column to make debugging MDX query results easier? For example, something like:
SELECT {
DESCENDANTS(...),
" --- end of descendants ---",
ASCENDANTS(...)
} ON ROWS

Yes you can, calulated members are the way. Take a look at the sample below where i have printed the current member, last member and next member
with member measures.CurrentName
as
[Product].[Product Line].currentmember.name
member measures.NextName
as
[Product].[Product Line].currentmember.nextmember.name
member measures.LastName
as
[Product].[Product Line].currentmember.prevmember.name
select {[Measures].[Internet Order Count],measures.CurrentName,measures.NextName,measures.LastName }
on 0,
[Product].[Product Line].[Product Line] on 1
from [Adventure Works]
Based on the comment below about adding a row
Here is a sample that adds row too.
with member measures.CurrentName
as
[Product].[Product Line].currentmember.name
member measures.NextName
as
[Product].[Product Line].currentmember.nextmember.name
member [Product].[Product Line].[CustomValue]
as
"End of descendants"
member measures.LastName
as
[Product].[Product Line].currentmember.prevmember.name
select {[Measures].[Internet Order Count],measures.CurrentName,measures.NextName,measures.LastName }
on 0,
{[Product].[Product Line].[Product Line],[Product].[Product Line].[CustomValue]} on 1
from [Adventure Works]

Related

MDX Get dimension count for each level of hierarchy

I have an MDX query which drills into a hierarchy - I need the count of a dimension for each level. I have tried a count function but it doesnt seem to work against each level:
member [RefIDCount] as distinctCount([Incident Details].[Process Safety Classification].&[Tier 1])
select
{
[RefIDCount]
} on columns,
{
DESCENDANTS(
[Reporting Hierarchies].[Hierarchy].[Reporting Category].&[49]
-- #RepCat#
)
} on rows
FROM [Monthly Stats]
This gives me the same count for each level :
What am I doing wrong? How do I get the count to be per level?
Take a look at the example below
with member measures.t
as
[Product].[Product Categories].currentmember.level.members.count
select
{[Measures].[Internet Sales Amount],measures.t}
on 0,
descendants([Product].[Product Categories].members
)
on 1
from
[Adventure Works]
Result

Write calculated member equivalent to scope assignment

I am trying to better understand scopes and calculated members better, so in the AdventureWorks database I did the following:
I wrote this simple scope statement:
SCOPE([Customer].[Customer].[All Customers], [Measures].[Average Rate]);
/* This expression sets the value of the Amount measure */
THIS = 999;
END SCOPE;
And equivalent calculated member will be this:
Create Member CurrentCube.[Measures].[My Measure]
AS
iif([Customer].[Customer].currentmember IS [Customer].[Customer].[All Customers], 999, [Measures].[Average Rate]);
But I am not sure how to create calculated member that will be equivalent to this scope assignment:
SCOPE([Customer].[Country].members, [Measures].[Average Rate]);
/* This expression sets the value of the Amount measure */
THIS = 999;
END SCOPE;
Actually I am not sure how to write iff that will check if current member of Customer dimension is a member of [Customer].[Country]
Here you go
///Will Display 999 for any member apart from All
with Member [Measures].[My Measure]
AS
iif([Customer].[Country].currentmember.Properties ("Member_Value",TYPED)='All Customers',[Measures].[Internet Sales Amount] , 999)
select {[Measures].[Internet Sales Amount],[Measures].[My Measure]}
on columns,
[Customer].[Country].members
on rows
from [Adventure Works]
///Will display 999 for any member
with Member [Measures].[My Measure]
AS
iif([Customer].[Country].currentmember.Properties ("Member_Value",TYPED)='WhatEver', 999, 999)
select {[Measures].[Internet Sales Amount],[Measures].[My Measure]}
on columns,
[Customer].[Country].members
on rows
from [Adventure Works]
//Below queries help to check if a member is part of a hierarchy
///////////////////////////////////////////////////////////////////////////
//Query checks if a Member is part of a hierarchy
with MEMBER TestIFAValidMember
as
[Product].[Subcategory].[InvalidMember].UniqueName
MEMBER TestIFAValidMember2
as
[Product].[Subcategory].[Caps].UniqueName
select {TestIFAValidMember,TestIFAValidMember2}
on columns
FROM [Adventure Works]
You can also try
WITH MEMBER MEASURES.NotMember AS
IsSibling([Product].[Category].CURRENTMEMBER, [Product].[Category].[Invalid])
MEMBER MEASURES.ISMember AS
IsSibling([Product].[Category].CURRENTMEMBER, [Product].[Category].[Bikes])
SELECT {MEASURES.NotMember,MEASURES.ISMember} ON 0,
[Product].[Category].MEMBERS ON 1
FROM [Adventure Works]

How to get number of the same members in mdx?

I would like to determine the number of particular weekdays (e.g. Mondays, Tuesdays, and so on....) between two dates. I thought something like the following should work, but member returns 1.
What have i done wrong?
WITH
MEMBER measures.NumberOfSameWeekDays AS
Count([Dim Date].[Day Of Week].CurrentMember)
SELECT
measures.NumberOfSameWeekDays ON COLUMNS
,[Dim Date].[Day Of Week].[Day Of Week] ON ROWS
FROM [test]
WHERE
(
[Dim Client].[Common Client UID].&[{ED8822E7-2873-4388-BC3A-CC553D939FC4}]
,
[Dim Date].[Date Int].&[20150701] : [Dim Date].[Date Int].&[20150731]
);
This is a proof of what is happening:
WITH
MEMBER measures.NumberOfSameWeekDays AS
Count([Date].[Day of Week].CurrentMember)
MEMBER measures.WeekDayCurrentMem AS
[Date].[Day of Week].CurrentMember.Member_Caption
SELECT
{
measures.NumberOfSameWeekDays
,measures.WeekDayCurrentMem
} ON COLUMNS
,[Date].[Day of Week].[Day of Week] ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Date].&[20050101]
:
[Date].[Calendar].[Date].&[20050116];
Here is the result of the above:
Here is a solution to the above behaviour:
WITH
MEMBER measures.NumberOfSameWeekDays AS
Count
(
(EXISTING
[Date].[Day of Week].CurrentMember * [Date].[Calendar].[Date])
)
SELECT
{
measures.NumberOfSameWeekDays
} ON COLUMNS
,[Date].[Day of Week].[Day of Week] ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Date].&[20050101]
:
[Date].[Calendar].[Date].&[20050131];
This returns the following:
A simplified version of Sourav's answer - although still rather complex - and potentially slow as it uses Generate which is iterative:
WITH
MEMBER Measures.CountOfDays AS
Generate
(
(EXISTING
[Date].[Date].[Date].MEMBERS)
,[Date].[Day of Week]
,ALL
).Count
SELECT
Measures.CountOfDays ON 0
,[Date].[Day of Week].[Day of Week].MEMBERS ON 1
FROM [Adventure Works]
WHERE
[Date].[Calendar].&[2005] : [Date].[Calendar].&[2006];
Adventure Works version:
WITH MEMBER Measures.CountOfDays AS
GENERATE
(
EXISTING [Date].[Date].[Date].MEMBERS,
EXISTING [Date].[Day of Week].[Day of Week].MEMBERS
,ALL
).COUNT
SELECT Measures.CountOfDays ON 0
,[Date].[Day of Week].[Day of Week].MEMBERS ON 1
FROM [Adventure Works]
WHERE [Date].[Calendar].&[2005]: [Date].[Calendar].&[2006]
The GENERATE part gets all the days of weeks in current context and based on whatever filter you might have.

Change Dates to numbers

This is the script:
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,Descendants
(
[Date].[Calendar].[Month].[August 2006]
,[Date].[Calendar].[Date]
,self
) ON ROWS
FROM [Adventure Works];
It returns this:
Can I change the script so that instead of dates it returns integers starting at either 0 or 1 i.e. the first would be 1 the second would be 2 etc.
This adds a counter but I'd like to get rid of the date column:
WITH
MEMBER [Measures].[r] AS
Rank
(
[Date].[Calendar].CurrentMember
,[Date].[Calendar].[Month].[August 2006].Children
)
SELECT
{
[Measures].[r]
,[Measures].[Internet Order Count]
} ON COLUMNS
,[Date].[Calendar].[Month].[August 2006].Children ON ROWS
FROM [Adventure Works];
This will be difficult, as what you have on the rows and columns are sets of tuples of members, either physical or calculated ones.
What you could do of course is this:
WITH Member [Date].[Calendar].[1] AS [Date].[Calendar].[Date].&[20060801]
Member [Date].[Calendar].[2] AS [Date].[Calendar].[Date].&[20060802]
...
Member [Date].[Calendar].[31] AS [Date].[Calendar].[Date].&[20060831]
SELECT
{
[Measures].[Internet Order Count]
} ON COLUMNS
,
{
[Date].[Calendar].[1],
[Date].[Calendar].[2],
...
[Date].[Calendar].[31]
}
ON ROWS
FROM [Adventure Works]
This may be feasible in case you generate the query with a tool.
However, in cases like this, I normally would keep the query like your second query, and just ignore the row headers in the client tool.

MDX query Count() return null when we put [Account].[Account Number].&[1] in WHERE clause

In our Adventure Works cube, if we run the following query, we will get two null cells back, and it will only happen for some members in Account Number. Does anyone know why?
Query that will return two cells with null value:
WITH MEMBER count1 AS 'Count(Crossjoin([Measures].[Amount], [Date].[Calendar Year].[Calendar Year]))'
MEMBER count2 AS 'Count(DrilldownLevel([Department].[Departments]))'
SELECT {count1, count2} ON 0 FROM [Adventure Works]
WHERE [Account].[Account Number].&[1]
Query that will return two cells with correct number:
WITH MEMBER count1 AS 'Count(Crossjoin([Measures].[Amount], [Date].[Calendar Year].[Calendar Year]))'
MEMBER count2 AS 'Count(DrilldownLevel([Department].[Departments]))'
SELECT {count1, count2} ON 0 FROM [Adventure Works]
WHERE [Account].[Account Number].&[4]
Does anyone know why adding "[Account].[Account Number].&[1]" in the WHERE clause will cause the Count() to return cell with null value?
Also, if we change the query to the following, it seems to give us the correct result. Does anyone know whether using Crossjoin is a right way to fix the problem?
WITH MEMBER count1 AS 'Count(Crossjoin(Crossjoin([Measures].[Amount], [Date].[Calendar Year].[Calendar Year]), [Account].[Account Number].&[1]))'
MEMBER count2 AS 'Count(Crossjoin(DrilldownLevel([Department].[Departments]), [Account].[Account Number].&[1]))'
SELECT {count1, count2} ON 0 FROM [Adventure Works]
Thanks,
Vivien
Try:
WITH
MEMBER [Measures].[count1] AS
Count(NonEmpty([Date].[Calendar Year].[Calendar Year],[Measures].[Amount]))
MEMBER [Measures].[count2] AS
Count(NonEmpty([Department].[Departments].[Departments].Members,[Measures].[Amount]))
SELECT
{
[Measures].[count1],
[Measures].[count2]
} ON 0
FROM [Adventure Works]
WHERE [Account].[Account Number].&[1]