How I can list levels for one dimension, which have non empty associated measure?
Let assume that I have measure Budget. We created budget four times in a year, so this measure contains all of these values. I need to check only one prediction (category) in the report.
This query returns me all levels:
WITH
MEMBER [Measures].[Label] AS [Dim_Budget Category].[Category].CURRENTMEMBER.MEMBER_CAPTION
MEMBER [Measures].[Value] AS [Dim_Budget Category].[Category].CURRENTMEMBER.UNIQUENAME
SELECT
{
[Measures].[Label],
[Measures].[Value]
} ON 0,
{
[Dim_Budget Category].[Category].&[BUDGET],
[Dim_Budget Category].[Category].&[YEP_1],
[Dim_Budget Category].[Category].&[YEP_2],
[Dim_Budget Category].[Category].&[YEP_3]
} ON 1
FROM [Retail]
Now I am trying to add logic which check If category have any value in measure Budget. If yes, the query should return this level.
To test if [Dim_Budget Category].[Category].&[YEP_1] is empty against a measure [Measures].[Budget] just wrap NonEmpty around it:
NonEmpty(
[Dim_Budget Category].[Category].&[YEP_1]
,[Measures].[Budget]
)
Related
I've been working on an ExcelDNA C# xll that allows users to enter simple words (under guidance) and I construct the elaborate MDX for them to query against a remote ActivePivot cube.
During testing I've ntoticed that when filtering, the grand total disappears (presumably it's joining tuples together). How do I still get a grand total? Do I need to use SCOPE or create a calculated member?
Thanks to more advanced MDX people:
SELECT
NON EMPTY
{
[Measures].[Notional.SUM]
,[Measures].[Notional.SHORT]
,[Measures].[Notional.LONG]
} ON COLUMNS
,NON EMPTY
Hierarchize
(
Filter
(
(
[CDR].[CDR].MEMBERS
,[Book].[Book].MEMBERS
)
,
Left([Book].[Book].CurrentMember.MemberValue,2) = "22"
)
,POST
) ON ROWS
FROM [TraderCube]
WHERE
[Date].[Date].[2020-01-24];
The following is something similar against AdvWrks cube:
WITH
//>>inside the WITH clause we have moved the set
SET [FilteredSet] AS
{
Filter
(
[Reseller].[Reseller Type].[Business Type].MEMBERS
,
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "sp"
OR
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "VA"
)
}
//>>next we create a custom member that is the sum of the filtered set
MEMBER [Reseller].[Reseller Type].[All Visible Resellers] AS
Aggregate([FilteredSet])
SELECT
NON EMPTY
{[Measures].[Reseller Sales Amount]} ON COLUMNS
,NON EMPTY
//>> inside these curly brackets we declare a set that is the filtered set and the Total member
{
[FilteredSet]
,[Reseller].[Reseller Type].[All Visible Resellers]
} ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Calendar Year].&[2013];
The results of the above is the following:
Here are two simple queries which shows data on month level filtered by dates.
In the first query I am using Month level of "Date.Calendar" user hierarchy.
SELECT
NON EMPTY { [Measures].[Internet Sales Amount] } ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM [Adventure Works]
WHERE {[Date].[Date].&[20130105]:[Date].[Date].&[20130106]}
And recieved - January 2013 -> $857,689.91
Results
In the second query I am using "Date.Month of Year" attribute hierarchy.
SELECT
NON EMPTY { [Measures].[Internet Sales Amount]} ON 0,
NON EMPTY { [Date].[Month of Year].&[1] } ON 1
FROM [Adventure Works]
WHERE { [Date].[Date].&[20130105] : [Date].[Date].&[20130106] }
And received - January -> $54,468.46
Results
I can not figure out why these two queries show different results. If the same dimension is used and data are filtered/sliced on the lovest possible level.
Here are values for each of these dates.
SELECT
NON EMPTY { [Measures].[Internet Sales Amount]} ON 0,
NON EMPTY { [Date].[Calendar].[Date] } ON 1
FROM [Adventure Works]
WHERE { [Date].[Date].&[20130105] : [Date].[Date].&[20130106] }
January 5, 2013 $32,681.44
January 6, 2013 $21,787.02
Result
Total value for these two dates is equal with the second querie's result - $54,468.46
I understand that in the first query it is user hierarchy and the second query it is attribute hierarchy from the Date dimension but I can not figure out which rule(s) tells to calculate these values differently.
If someone could explain this logic behind - it would be very helpful. Any link to some resource which explains this logic also could help.
BTW: I have created simple cube with simple Date dimension which consists just of attribute hierrarchies (date, month, year) and it still works like in the first query so it is not clear why it behaves like that.
I explored the reason for this behavior, and I think I have figured out the reason. The explanation below is based on the book SQL SERVER 2008 MDX Step by Step pages 51-58(especially Avoiding Reference Conflicts).
Your problem is a typical Reference Conflict problem.In MDX a hierarchy cannot be used more than once in a given tuple, but if you are using a USER Hierarchy and its under lying Attribute Hierarchy, you essentially by-pass this check. This is what happened in your query
In your first query you are using the User Hierarchy
[Date].[Calendar].[Month].&[2013]&1
In MDX a User Hierarchy is translated to Attribute Hierarchies. In your first query
SELECT
NON EMPTY { [Measures].[Internet Sales Amount] } ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&1 } ON 1
FROM [Adventure Works] WHERE
{[Date].[Date].&[20130105]:[Date].[Date].&[20130106]}
you are using a User Hierarchy "[Date].[Calendar].[Month].&[2013]&1", which in its last level has "[Date].[Date]". Then in the where clause you use the same "[Date].[Date]" Attribute Hierarchy to filter. Since in the USER Hierarchy you have not used the leaf level, hence you have made a partial address, therefore the members and its ancestors are resolved. All the descendants are ignored in translation. Take a look at the below query(This is based on your first query,I have purposely removed your where clause).
with member [Measures].[CalendarYear] as [Date].[Calendar Year].currentmember.name
member [Measures].[CalendarSemester] as [Date].[Calendar Semester of Year].currentmember.name
member [Measures].[CalendarQuater] as [Date].[Calendar Quarter of Year].currentmember.name
member [Measures].[CalendarMonth] as [Date].[Month of Year].currentmember.name
member [Measures].[CalendarDate] as [Date].[Date].currentmember.name
SELECT
NON EMPTY { [Measures].[Internet Sales Amount] ,[Measures].[CalendarYear],[Measures].[CalendarSemester],[Measures].[CalendarQuater],[Measures].[CalendarMonth],[Measures].[CalendarDate]} ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM [Adventure Works]
Result.
Notice that Calendar year, Semester and quarter all are showing non-default values. But we never used them. This shows that translation of User Hierarchy is done into underlying Attribute Hierarchies. Now take a look at Calendar, it is still showing "All Period". Since it was ignored.
Now if you add your where clause back, the Date still shows "All Period", there are two reasons
1) Because it was ignored in User Hierarchy translation ,
2)You used a range in where. If you replace your row axis tuple with your where tuple it will still show "All Period" as a range is based. However while resolving it will take just two dates.
Based on this while resolving your query, it had two translation for Date attribute hierarchy, one said to ignore it based on User Hierarchy, the other provided a range. This is where due to conflict the result is in-correct.
Now lets consider the query you gave me in your comment earlier
with member [Measures].[CalendarYear] as [Date].[Calendar Year].currentmember.name
member [Measures].[CalendarSemester] as [Date].[Calendar Semester of Year].currentmember.name
member [Measures].[CalendarQuater] as [Date].[Calendar Quarter of Year].currentmember.name
member [Measures].[CalendarMonth] as [Date].[Month of Year].currentmember.name
member [Measures].[CalendarDate] as [Date].[Date].currentmember.name
SELECT
NON EMPTY { [Measures].[Internet Sales Amount] ,[Measures].[CalendarYear],[Measures].[CalendarSemester],[Measures].[CalendarQuater],[Measures].[CalendarMonth],[Measures].[CalendarDate]} ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM [Adventure Works]
WHERE {[Date].[Date].&[20130105]}
Result:
Notice that this time the resolution of a single member, was used instead of the User hierarchy resolution. Now this behavior might be due to the fact that one translation is giving "All Period" and the next is giving a member, hence the member won.
To further confirm this, I made a change to my AdventureWorks sample. The Date attribute hierarchy is based on "Simple Date" column. I exposed "Simple Date" as a separate attribute and processed my cube.
Take a look at the "Simple Date" query and results.
with member [Measures].[CalendarYear] as [Date].[Calendar Year].currentmember.name
member [Measures].[CalendarSemester] as [Date].[Calendar Semester of Year].currentmember.name
member [Measures].[CalendarQuater] as [Date].[Calendar Quarter of Year].currentmember.name
member [Measures].[CalendarMonth] as [Date].[Month of Year].currentmember.name
member [Measures].[CalendarDate] as [Date].[Date].currentmember.name
SELECT
NON EMPTY { [Measures].[Internet Sales Amount] ,[Measures].[CalendarYear],[Measures].[CalendarSemester],[Measures].[CalendarQuater],[Measures].[CalendarMonth],[Measures].[CalendarDate]} ON 0,
NON EMPTY { [Date].[Calendar].[Month].&[2013]&[1] } ON 1
FROM [Adventure Works]
WHERE
--{[Date].[Date].&[20130105]}
{[Date].[Simple Date].&[20130105]:[Date].[Simple Date].&[20130106]}
Results:
The following script gives exactly the result I want.
It feels like a hack as I've added the custom members VALUE and VALUE_MTD onto the hierarchy [Customer].[Country]. I've chosen this hierarchy arbitrarily - just not used [Measures] or [Date].[Calendar] as they are already in use.
Is there a more standard approach to returning exactly the same set of cells?
WITH
MEMBER [Customer].[Country].[VALUE] AS
Aggregate([Customer].[Country].[(All)].MEMBERS)
MEMBER [Customer].[Country].[VALUE_MTD] AS
Aggregate
(
PeriodsToDate
(
[Date].[Calendar].[Month]
,[Date].[Calendar].CurrentMember
)
,[Customer].[Country].[VALUE]
)
SELECT
{
[Customer].[Country].[VALUE]
,[Customer].[Country].[VALUE_MTD]
} ON 0
,NON EMPTY
{
[Measures].[Internet Sales Amount]
,[Measures].[Internet Order Quantity]
}
*
Descendants
(
{
[Date].[Calendar].[Month].&[2007]&[12]
:
[Date].[Calendar].[Month].&[2008]&[01]
}
,[Date].[Calendar].[Date]
) ON 1
FROM [Adventure Works];
The standard approach is called utility dimension. If you Google this term, you will find several descriptions of this approach. A "utility dimension" is one which does not reference any data, but is just added to the cube for the purpose of being able to cross join them with all other dimensions for calculations. You can have one or more of them.
Thus, in most cases, physically there is nothing in the dimension. It is just used for calculated members. (Depending on the implementation, you may have the attribute members defined physically, if you want to have some properties for them. But then, only the default member is referenced in the star schema from the fact tables. The attribute member values are then overwritten in the calculation script.)
Typical applications for this are time calculations like YTD, MTD, MAT (Moving Annual Total, i. e. a full year of data ending in the selected date), or comparisons like growth vs. a previous period.
Here is the query that I am using:
SELECT
NON EMPTY { [Dim Date].[Week].[Week].Members } ON COLUMNS,
[Dim Source].[Source Name].[Source Name].Members ON ROWS
FROM [Some Cube];
The things is, right now, I have many measures.
But as I am using dimension members on COLUMNS, I cannot indicate the measure anymore.
So this query results in a default measure.
My question is how can I indicate the measure instead of using the default in mdx query?
Or is there any other way that I can do this query (dimension in both row and columns is required for reading result logic in C# in possible) ?
You can do it in two ways:
Either on the SELECT statement, as
{ [Dim Date].[Week].[Week].Members } * { [Measures].[My Measure] } ON COLUMNS,
or on the WHERE slicer by adding
WHERE [Measures].[My Measure]
at the end.
I've faced a issue with MDX query, that I don't know how to workaround. I have following query:
SELECT
{
[Measures].[Cost],
[Measures].[Non additive]
} ON COLUMNS,
NON EMPTY
{
[Organization].[Organization Name].[Organization Name].MEMBERS
*[Time].[Month].[Month].MEMBERS
*[Region].[City].[City].MEMBERS
} ON ROWS
FROM [Cube]
And I would like to display "[Measures].[Non additive]" not at the lowest grouping level, but at the Organization Level. Is it possible?
Thanks for any help.
When I have a measure I don't walways want to display, I make a copy of it and include a test for the level of the current cell.
WITH MEMBER [Measures].[My New Measure Name]
AS 'IIF(IsLeaf([Organization].currentMember), NULL, [Measures].[Non additive])'
SELECT
{
[Measures].[Cost],
[Measures].[My New Measure Name]
} ON COLUMNS,
NON EMPTY
{
[Organization].[Organization Name].[Organization Name].MEMBERS
*[Time].[Month].[Month].MEMBERS
*[Region].[City].[City].MEMBERS
} ON ROWS
FROM [Cube]
The new measure tests whether the Organisation member is at the leaf level (the bottom of the hierarchy). If so it returns blank. If not, it returns the value of the old measure.
If you want more control, test if [Organisation].level = [Organisation].levels(1) and vary the number to detect which level you want (lower levels are higher numbers).