Please consider this MDX query:
SELECT {[Measures].[Internet Sales Amount]} ON COLUMNS,
[Date].[Calendar Year].MEMBERS ON ROWS
FROM [Adventure Works]
How Can I add WHERE clause to above query with these three criteria:
1) Where [Customer].[Customer Geography].[Country].&[United States] AND [Product].[Category].&[Bike]
2) Where [Customer].[Customer Geography].[Country].&[United States] OR [Product].[Category].&[Bike]
3) Where ([Customer].[Customer Geography].[Country].&[United States] OR [Product].[Category].&[Bike]) AND [Date].[Year].&[2008]
Thanks
1) Where [Customer].[Customer Geography].[Country].&[United States]
AND [Product].[Category].&[Bike]
For this your where clause will be
Where ([Customer].[Customer Geography].[Country].&[United States], [Product].[Category].&[Bike])
The above code defines a tuple which consits of data on from United States Bikes Sales
2) Where [Customer].[Customer Geography].[Country].&[United States] OR
[Product].[Category].&[Bike]
For this your Where clause will be
Where
{([Customer].[Customer Geography].[Country].&[United States], [Product].[Category].defaultmember),
([Customer].[Customer Geography].[Country].[Country], [Product].[Category].&[Bike])}
In this case you want data when either the country is USA or the Product is bike. So I have defined two tuples the first one says that country is USA and the product category can be any product category. In the next tuple I say that the country can be any country but the product is Bike. In MDX each Tuple with in a set should be equal in terms of hierarchy and in terms of the position of hierarchy. In the above case i cannot make a set saying
{
([Customer].[Customer Geography].[Country].&[United States]),
([Product].[Category].&[Bike])
}
This Set is not possible in MDX, therefore in the first tuple I mentioned
"[Product].[Category].defaultmember" which means no particular value is defined, similarly in the next tuple i used "[Customer].[Customer Geography].[Country].[Country]" since this is user hierarchy I cannot use default member, so I used this expression.
3) Where ([Customer].[Customer Geography].[Country].&[United States]
OR [Product].[Category].&[Bike]) AND [Date].[Year].&[2008]
For this you need to modify the where clause and the on rows. So for this part your query will be
SELECT {[Measures].[Internet Sales Amount]} ON COLUMNS,
[Date].[Calendar Year].&[2011] ON ROWS -- in my sample the strong name of 2011 is &[2011] yours may be diffrent
FROM [Adventure Works]
Where
{([Customer].[Customer Geography].[Country].&[United States], [Product].[Category].defaultmember),
([Customer].[Customer Geography].[Country].[Country], [Product].[Category].&[Bike])}
Related
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]
I would like to define a measure that will count dimension members by other dimension and add it as a measure on the cube.
Should I create a new measure group with a count of the attribute of dimension or it's better to create a calculated member?
Example on adventureworks: count products by ProductCategory
WITH
MEMBER [Measures].[Number of Products] AS
Count(Existing
[Product].[Product].[Product].Members
)
SELECT
[Measures].[Number of Products] on 0,
{[Product].[Category].Members} ON ROWS
FROM [Adventure Works]
You haven't given details, but my guess is that your current code will return the count of all products, repeated for each Product Category.
I don't have a working copy of Adventureworks to hand, but if Product is a level one level below Product Category in hierarchy "ProductHierarchy" on the Product dimension, this should work:
WITH MEMBER [Measures].[Number of Products] AS
Count([Product].[ProductHierarchy].CurrentMember.Descendants)
SELECT
[Measures].[Number of Products] ON 0,
{[Product].[Category].Members} ON 1
FROM [Adventure WOrks]
One of the functions being used in a code sample is averageofchilren.
What exactly the AverageOfChildren aggregate function actually does?
How can we compare this with Avg() function in MDX ?
Maybe a custom measure is created in your cube.
Using AdventureWorks try this:
Script 1
SELECT
{[Measures].[Reseller Sales Amount]} ON 0,
NON EMPTY
{[Geography].[Geography].[Country].&[Australia].CHILDREN} ON 1
FROM [Adventure Works]
WHERE ([Date].[Calendar Year].&[2007])
That results in this:
Say I wanted to create a measure that returned the average reseller sales amount per region of each country then I could do the following:
Script 2
WITH
MEMBER [Measures].[AvgOfChildren] AS
AVG(
[Geography].[Geography].CURRENTMEMBER.CHILDREN,
[Measures].[Reseller Sales Amount]
)
SELECT
{ [Measures].[Reseller Sales Amount],
[Measures].[AvgOfChildren]
} ON 0,
{[Geography].[Geography].[Country].MEMBERS} ON 1
FROM [Adventure Works]
WHERE ([Date].[Calendar Year].&[2007])
You can see from the results for Australia (211,857.58) that the AverageOfChildren is the average of the numbers returned by script 1:
If I run the following there’s a whole section of Customers that are (null) internet sales amount for both 2007 and 2008 – why is this? How do I use EXISTS to filter to just customers who have results for the years in the select
note: The choice of years could vary so InitialSet needs to be context aware hence I've used [Date].[Calendar Weeks].CURRENTMEMBER withing the EXISTS function.
WITH
SET [InitialSet] AS
EXISTS(
{[Customer].[Customer].[Customer].MEMBERS},
[Date].[Calendar Weeks].CURRENTMEMBER,
'Internet Sales'
)
SET [OrderedSet] AS
NONEMPTY
(
ORDER
(
[InitialSet],
[Measures].[Internet Sales Amount],
BDESC
)
,([Measures].[Internet Sales Amount],[Date].[Calendar Weeks].CURRENTMEMBER)
)
SELECT
{
[Date].[Calendar Weeks].[Calendar Year].&[2007],
[Date].[Calendar Weeks].[Calendar Year].&[2008]
} ON 0,
[OrderedSet] ON 1
FROM [Adventure Works]
WHERE (
[Measures].[Internet Sales Amount]
);
Sets are evaluated by Analysis Services by taking the WHERE clause into account, but not using any row or column settings. If you would like to evaluate the sets only for 2007 and 2008, you have to state that.
Actually, the [Date].[Calendar Weeks].CURRENTMEMBER in your first set will refer to the default member of the [Date].[Calendar Weeks] hierarchy, which is the All member.
I am trying to create a dataset for an SSRS report as documented here:
http://sqlblog.com/blogs/stacia_misner/archive/2010/10/08/29249.aspx
The challenge is that I have multiple measures who's data I want to include in the measure column and I want to include the name of the measure in the RowValue column. So where the following query returns only data for measure "Sales Amount":
with
member [Measures].[Measure] as [Measures].[Sales Amount]
member [Measures].[RowValue] as [Product].[Category].CurrentMember.Name
member [Measures].[ColumnValue] as [Date].[Calendar Year].CurrentMember.Name
select {[Measures].[Measure], [Measures].[RowValue], [Measures].[ColumnValue]} on columns,
non empty ([Product].[Category].[Category].Members, [Date].[Calendar Year].[Calendar Year].Members) on rows
from [Adventure Works]
What I want to do is run the following type of query but have the data returned in the structure of the query above which would allow me to plug it into an SSRS report matrix:
WITH
MEMBER measures.SalesAmount AS [Measures].[Sales Amount]
MEMBER measures.CustomerCount AS [Measures].[Customer Count]
MEMBER measures.InternetFreightCost AS [Measures].[Internet Freight Cost]
SELECT [Date].[Calendar Year].[Calendar Year].Members ON COLUMNS,
{measures.SalesAmount,measures.CustomerCount,measures.InternetFreightCost} ON ROWS
FROM [Adventure Works]
Do any of the MDX ninjas know if this is even possible with MDX?
with member [Geography].[City].[Sales Amount] as 1
member [Geography].[City].[Customer Count] as 1
member [Geography].[City].[Freight Cost] as 1
member [Measures].[RowValue] as [Geography].[City].CurrentMember.Name
member [Measures].[ColumnValue] as [Date].[Calendar Year].CurrentMember.Name
member [Measures].[Measure] as
CASE
WHEN [Geography].[City].CurrentMember IS [Geography].[City].[Sales Amount]
THEN ([Measures].[Internet Sales Amount], [Geography].[City].[All Geographies])
WHEN [Geography].[City].CurrentMember IS [Geography].[City].[Customer Count]
THEN ([Measures].[Customer Count], [Geography].[City].[All Geographies])
WHEN [Geography].[City].CurrentMember IS [Geography].[City].[Freight Cost]
THEN ([Measures].[Internet Freight Cost], [Geography].[City].[All Geographies])
END
select {[Measures].[RowValue], [Measures].[ColumnValue], [Measures].[Measure]}
on columns,
{ [Geography].[City].[Sales Amount], [Geography].[City].[Customer Count], [Geography].[City].[Freight Cost]}
*
[Date].[Calendar Year].[Calendar Year].Members
having [Measures].[Measure] <> null
on rows
from [Adventure Works]
should deliver what you want. I used [Geography].[City] as an utility hierarchy. This can be any hierarchy unused in the query. I chose this one, as it is unrelated to both measure groups used in the query, and hence very unlikely to be used in any query. Some Cube designers create one or two one-member dummy dimensions in their cubes that are unrelated to any measure group, and can be used just like here in order to create calculated members on them.
One of the difficulties with ReportingServices queries is that measures must always be in the columns, and no other hierarchy may be in the columns. Hence, if we want to have the measures in the rows, we must move them to another hierarchy. This is done in two steps: First, we create dummy members on the utility hierarchy, and then map these to the measure needed in the CASE construct of the [Measures].[Measure] definition, where we need to use the default member of the utility dimension (in most cases the All member) in order to get something different than the 1 that I used for the dummy value.
Finally: non empty does not work properly with this construct, as [Measures].[RowValue] and [Measures].[ColumnValue] are never null. Hence I replaced it by HAVING, which can look at specific column values within the row.