I made my first cube yesterday. I'm still new to this, so please forgive any misuse of terminology. One of my dimensions, let's call it MyDimension1 has a hierarchy, let's call it MyHierarchy, with two levels, let's call them Level1 and Level2.
I seem to be able to do something like:
SELECT
{ [Measures].[Whatever] } ON 0,
{ ([MyDimension1].[Level1].[Level1], [MyDimension1].[Level2].[Level2]) } ON 1
FROM MyCube
Which gives me the result I want. If I understand correctly, the set defining axis 1 contains a tuple with two components(?). I've read that each component(?) of a tuple is supposed to be from a different dimension, but I seem to be able to specify components of the same dimension, as demonstrated by the above query. I'd like to be able to just specify the hierarchy by name and then have the server create the tuples for me, though. So something like:
SELECT
{ [Measures].[Whatever] } ON 0,
{ AllLevelsToTuple([MyDimension1].[MyHierarchy]) } ON 1
FROM MyCube
But I can't seem to figure out how to do this. Thanks in advance!
EDIT (My example, as requested by an answerer):
This does what I want, functionally, but isn't the syntax I'd like:
SELECT [Measures].[Original] ON 0,
([Customer].[Customer].[Customer], [Customer].[Account ID].[Account ID]) ON 1
Results (In SSMS):
Original
--------- -- --------
CustomerA 15 306.03
CustomerA 16 754.20
...
CustomerB 17 524.43
...
CustomerC 22 760.42
...
When I expand the dimension, it looks like:
- Customer
- Hierarchy
+ Members
+ Customer
+ Account ID
When I do something like (I'd like to do something similar syntactically):
SELECT [Measures].[Original] ON 0,
([Customer].[Hierarchy].Members) ON 1
I get the following results:
Original
---------- --------
All 17638.15
CustomerA 2624.76
15
16
...
CustomerB 3113.67
17 524.43
...
CustomerC 3427.01
22 760.42
...
I want there to be 3 columns, not 2, basically.
You might want to read this MDX gentle introduction.
I've read that each component(?) of a tuple is supposed to be from a
different dimension
From different hierarchy instead. In AS, I guess that for each level, you have as well a corresponding flat hierarchy; so the following looks like you're accessing levels of two different hierarchies:
{ ([MyDimension1].[Level1].[Level1], [MyDimension1].[Level2].[Level2]) } ON 1
I'm not a specialist of AS but I guess the following statement :
SELECT [Measures].[Original] ON 0,
([Customer].[Customer].[Customer], [Customer].[Account ID].[Account ID]) ON 1
is actually interpreted as a crossjoin of level members from 2 different hierarchies; it is more likely that the () notation is interpreted as the () operator instead of tuple notation and then {},{} is a crossjoin in MDX :
SELECT [Measures].[Original] ON 0,
[Customer].[Customer].[Customer].members * [Customer].[Account ID].[Account ID].members ON 1
hence the two columns in front of your measures in the result.
I want there to be 3 columns, not 2, basically.
You'll need to use calculated measures; something like :
with
MEMBER Measures.HN as [Customer].Currentmember.Hierarchy.Name
MEMBER Measures.LN as [Customer].Currentmember.Level.Name
MEMBER Measures.MN as [Customer].Currentmember.Name
SELECT { Measures.HN, Measures.LN, Measures.MN, [Measures].[Original] } ON 0,
([Customer].[Hierarchy].Members) ON 1
Yes, you can create a tuple from different dimensions, and you do so by placing members between parentheses and separated by commas.
But in this case, you don't need a tuple, simply a set. A set contains members from a single dimension, separated by commas and placed between curly braces: {}.
Have a look at the descendants function. You can create a set from your hierarchy using this function.
Related
I struggling with conditional grouping of some members within query.
In my simplified example I have two dimensions and one measure. The first dimension contains some categories and the second dimension some units. In all but one category, all categories have a single unit (category A and B in the example). However, one category has multiple units. If I put both dimensions on rows I get multiple results for category C (as in the following example). What I really need is to get one line per category, with the Amount appropriately aggregated but also with the displayed units (in case of category C, they should be replaced either by single "none" or concatenated together if this is not possible ("km, kg" in the example)).
The following example should illustrate what I am trying to achieve.
With the following query:
SELECT
NON EMPTY { [Measures].[Amount] } ON COLUMNS,
NON EMPTY { ([Grouping A].[Category].[Category].ALLMEMBERS *
[Grouping B].[Unit].[Unit].ALLMEMBERS ) } ON ROWS
FROM [ExampleCube]
I get data like this:
Category Unit Amount
A km 10
B km 5
C km 5
C kg 2
C km 5
But what I really need to achieve is to group the dimension Category and treat the dimension Unit and measure Amount appropriately as follows:
Category Unit Amount
A km 10
B km 5
C none 12
Maybe this is really simple but I have been trying to solve this for a while with no results.
Any ideas would be appreciated.
Thanks.
It's not simple. OLAP hasn't been designed for this kind of things.
Nonetheless, you can solve it in the following way:
With
[Measures].[Unit] as
IIF(
NonEmpty(
[Grouping B].[Unit].[Unit].Members,
[Measures].[Amount]
).Count > 1,
"None",
NonEmpty(
[Grouping B].[Unit].[Unit].Members,
[Measures].[Amount]
).Item(0).Name
)
Select
Non Empty { [Measures].[Unit],[Measures].[Amount] } on 0,
Non Empty { [Grouping A].[Category].[Category].Members } on 1
From [ExampleCube]
I'm trying to write a MDX query that would display all my products and the subgroups (hierarchy parent) that they belong to. While the task seems rather trivial i still can't figure it out. Here is my MDX query.
select
{
[Products].[Hierarchy].currentmember.parent
}
on 0,
{
[Products].[Hierarchy].[Product].members
}
on 1
from [CUBE]
I also tried
select
{
Ancestor([Products].[Hierarchy].currentmember,
[Products].[Hierarchy].[Subgroup])
}
on 0,
{
[Products].[Hierarchy].[Product].members
}
on 1
from [CUBE];
But all I get from it is a gray list of products without any actual column. Any help/tips would be greatly appreciated.
If you want to use the same hierarchy then you can only use it on one axis - there are 3 axis in context - ON COLUMNS / ON ROWS / WHERE.
So putting [Products].[Hierarchy]. ON COLUMNS and also ON ROWS would throw an exception.
What you can do is move some of the logic into a WITH clause and move the narrative into the Measures dimension:
WITH
MEMBER [Measures].[ProdName] AS
Ancestor(
[Products].[Hierarchy].currentmember,
[Products].[Hierarchy].[Subgroup]
).MEMBER_CAPTION
SELECT
[Measures].[ProdName] ON 0,
[Products].[Hierarchy].[Product].MEMBERS ON 1
FROM [CUBE];
You could make use of your attribute hierarchies and do something like this:
SELECT
{} ON 0,
[Products].[Product].[Product]
*[Products].[Subgroup].[Subgroup]
ON 1
FROM [CUBE];
In MDX, we can CROSS JOIN two members, a measure and a member but not two measures. Why is this so? What does it imply?
SELECT
[Measures].[xyz] * [DimTable1].[SomeHierarchy].[Level] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] on 1
FROM [MyCube]
// WORKS
SELECT
[Measures].[xyz] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] * [DimTable1].[SomeHierarchy].[Level] on 1
FROM [MyCube]
// OF COURSE IT WORKS
SELECT
[Measures].[xyz] * [Measures].[ABC] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1
FROM [MyCube]
// DOES NOT WORK!!
I believe you forgot:
SELECT
[dd].[hh].[mm1] * [dd].[hh].[mm2] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1 FROM [MyCube]
did not work neither. [Measures] is not different than [dd] in my example. In MDX you cannot define a tuple with _ several members _ of the _ same hierarchy _. Have a look to this gentle introduction explaining the main concepts.
EDIT
Your third query, that does not work, looks like this:
The yellow area is empty so it is understandable that it is not happy.
EDIT
Following is an analogy using Excel pivot tables which use OLAP technology
If you put a crossjoin of measures A and B on rows you get something like this:
Then if we add a very small level (with 4 members) onto columns we get the following:
So what will go into the main body of this table?
A count is possible and probably is, in MDX, if you create a custom measure (don't have a server to test this statement on). Excel will default to a count but the result is pretty pointless?
i have a huge table of cashflows that means there are +int values for income and -int values for outcome.
I have MeasureGroup for Sum the amount of money.
I now want to display not only the sum of money per month but also the sum of all the past time until the current month so like that:
Month MoneyAmount Total
1 20 20
2 -10 10
3 5 15
4 -10 5
So i know for the first part its just like
select [Measures].[Money] on 0,
[Date].[Month].Members on 1
From MyCube
but how can i add the sum column?
i thought about something like SUM( { NULL : [Date].[Month].CurrentMember } , [Measures].[Money] ) but that didnt work as well :(
In MDX, the total is already there. You do not have to do complex calculations to get it.
But it depends on your exact hierarchy structure how the All member is called. If you have a date user hierarchy named [Date].[Date], and it has a month level named [Date].[Date].[Month], then the all member of the hierarchy would probably be called something like [Date].[Date].[All]. If [Month] is an attribute hierarchy of the Date dimension, then the "all member" would probably be called [Date].[Month].[All]. In the latter case, the all member would already be the first member of the set [Date].[Month].Members. As you are asking the question, I am assuming this is not the case, and you are using a user hierarchy. Then you could change your MDX query to
select [Measures].[Money] on 0,
Union([Date].[Month].Members, { [Date].[Date].[All] }) on 1
From MyCube
Please note that you can change the name of the All member in the property settings of a dimension when designing an Analysis Services dimension, hence I cannot know the definitive name without knowing the details of this setting in your cube. So you might have to adapt the name of the all member.
You can find this name out in SQL Server Management Studio in an MDX window as follows: open the hierarchy that you are using, and then open the "Members" node, below which you should find the "All Member". You can drag this into your MDX statement, and the proper name will appear there.
As in a running sum?
You need a calculated measure, like this:
With Member [Measures].[Running Sum] as Sum( ( [Date].[Months].Members.Item(0) : [Date].[Months].CurrentMember ), [Measures].[Money])
Select [Date].[Months].Members on Rows,
{[Measures].[Money], [Measures].[Running Sum] } on Columns
From [MyCube]
I've just started to learn MDX and i want to do a query like that:
filter data by the cost ( i've already made that query but without the sum) like that:
SELECT [Measures].[SumOfSelled] ON 0,
FILTER ([From].[From].[City].members, [Measures].[SumOfSelled]>7000) ON 1
FROM [BI-Avia]
It's working
and it is OK
BUT!!!
I need also to show the sum of filtered elements under this filtered result by cities
I know how to find it separately:
with member [Measures].FilteredSum as sum(filter([From].From].City].members,Measures].SunOfSelled]>7000),Measures].[SumOfSelled])
select{SumOfSelled} on 0
from [BI-AVIA]
But i have to show this together!! The SUM under Filtered! two in one! I need youe help! I think it's very clear for you!!!
Just define the calculated member on the [From].[From] hierarchy and then combine both queries, using a union of sets (abbreviated with + in MDX):
with member [From].[From].FilteredSum as
sum(filter([From].[From].City].members, Measures].SumOfSelled]>7000))
SELECT [Measures].[SumOfSelled]
ON 0,
FILTER ([From].[From].[City].members, [Measures].[SumOfSelled]>7000)
+
{ [From].[From].FilteredSum }
ON 1
FROM [BI-Avia]
You could possibly define the filter as a set in the WITH clause, which would avoid that Analysis Services evaluates it twice.