I am trying to merge the result of two separate MDX queries, where the measures are from the same measure group. The cube design is based on a lifecycle transaction model, where the date are all role playing dimensions. The queries are:
select [Measures].[Issued] on columns,
[Product].[Product Name].[Product Name] on rows
from [MET2DW]
where ([Product].[Product Type].&[IP], [Product].[Component Type].&[SD],[Issued Date].[Fiscal Year Name].&[Fiscal Calendar 2010])
select [Measures].[Last hits] on columns,
[Product].[Product Name].[Product Name] on rows
from [MET2DW]
where ([Product].[Product Type].&[IP], [Product].[Component Type].&[SD],[Last Sync Date].[Fiscal Year Name].&[Fiscal Calendar 2010])
I've tried using a CROSSJOIN, but then it complained about the fact that the measures I was trying to cross join are in the same heirarchy. If I run the query with both the measures on the same set, then the date filters don't really work anymore. The issue is basically that they are different date dimensions for each of those counts, and they slice different ways.....
Is there any way to do this?
You can create a MDX calculated member adding both values for two tuple of different dimensionality (aka same hierarchies):
with
member [Measures].[-Issued] as ([Issued Date].[Fiscal Year Name].&[Fiscal Calendar 2010],[Measures].[Issued])
member [Measures].[-Last hits] as ([Last Sync Date].[Fiscal Year Name].&[Fiscal Calendar 2010],[Measures].[Last hits])
select
{[Measures].[-Issued],[Measures].[-Last hits]} on columns,
[Product].[Product Name].[Product Name] on rows
from
[MET2DW]
where
([Product].[Product Type].&[IP], [Product].[Component Type].&[SD])
Related
In MDX, is it possible to slice one measure by another?
E.g. suppose I have a cube which includes two measures: Order Value ($) and Order Quantity (#). Can I write a query that will tell me the number of orders with an order value over $1000?
I'd suggest two ways:
Add Order Value as separate dimension and filter out all values which are less than $1000.
Add Order dimension and filter them out with a calculated measure.
MDX formula:
SUM(
existing [OrderDim].[OrderHier].[OrderAttr].Members,
IIF(
[Measures].[Order Value] > 1000,
1,
Null
)
)
I need to product a report from my cube that looks something like the following.
(dummy data)
Where it lists sales and gross profit for today, this week, the period and year to date across the products category.
My cube is setup as follows
A date dimension
And the cube itself
Currently I have not implemented the product category pieces.
I'm struggling with how to write an MDX query that can return the sales/gross profit for a single day and then week and so on.
I can return it by itself like so
SELECT {[Measures].[Gross Profit],[Measures].[Price]} ON COLUMNS
From [Cube]
WHERE [Date].[Date Key].[2015-04-22];
and so on for the other various types (week etc), but I'm unsure as how to apply the where filter to the columnn itself rather than the overall query, or if this is even the correct way to do it and I should be making multiple MDX calls that I then compose in my app that will use this.
Can anyone give me a pointer in the right direction here?
EDIT: Seems to mostly work using the approach #Akshay Rane described however I cannot get one of my measures to work
MEMBER [This Week] as
(PeriodsToDate([Date].[Fiscal Week Date].[Fiscal Week],StrToMember('[Date].[Fiscal Week Date].[Date Key].&[' + '20140401' + ']'))
,[Measures].[Merchandise Gross Profit])
Gives me an error:
The function expects a string or numeric expression for the argument. A tuple set expression was used.
Any pointers here?
You will have to create separate Calculated Members for each time interval you want to aggregate the data upon.
This can be done in [Adventure Works] cube as follows.
WITH
MEMBER [Today] as
([Measures].[Internet Sales Amount], [Date].[Date].CURRENTMEMBER)
MEMBER [Last Week] as
AGGREGATE (
{ [Date].[Date].CURRENTMEMBER.lag(6) : [Date].[Date].CURRENTMEMBER }
, [Measures].[Internet Sales Amount]
)
SELECT
{ [Today], [Last Week] } ON 0,
{ ([Product].[Product Categories].[Category], [Date].[Date].[Date]) } ON 1
FROM
(
/*FILTERING ON SPECIFIC DATE USING SUBCUBE*/
SELECT [Date].[Date].&[20070715] ON 0
FROM [Adventure Works]
)
If you can take the different levels of date from the same user hierarchy then something like this is possible:
SELECT
{
[Date].[Calendar].[Month].&[2006]&[7]
,[Date].[Calendar].[Date].&[20050220]
}
*
{
[Measures].[Order Quantity]
,[Measures].[Internet Sales Amount]
} ON COLUMNS
,{[Product].[Category].Children} ON ROWS
FROM [Adventure Works];
The above produces results like this:
SSAS 2012, AdventureWorks Tabular Model SQL 2012
Having a hierarchy of some fields, want to list values from a measure per month in a year, then see average value for month, then sum these averages on all hierarchy levels up.
Example: (all measures in table 'Internet Sales')
ComplexCalculation:=[Internet Total Sales]*[UnitPriceAvg]/1000
UnitPriceAvg:=AVERAGE('Internet Sales'[Unit Price])
AvgComplexCalculation:=AVERAGEX(VALUES('Date'[Month]), [ComplexCalculation])
AverageAndSumComplexCalculation:=IF( ISFILTERED(Product[Product Name]), [AvgComplexCalculation], SUMX (VALUES (Product[Product Name]), [AvgComplexCalculation]))
Pivot Fields:
Filters: [Calendar Year] [2006]
Rows: [Product Category Name],[Product SubCategory Name],[Model Name],[Product Name],[Month]
Columns:
Values: [AverageAndSumComplexCalculation]
Is it the right way of doing this? Noticed that when my "ComplexCalculation" measure becomes more and more complex it needs lot of time to calculate the values (causes timeout).
How do I use percentile (let's say 99% percentile) as a measure in SSAS cube? I'd like to be able to report on it using many different dimensions and filters so pre-calculating in sql is not an option.
If you want to evaluate percentiles over a dimension, then you can do it without having to pre-calculate anything in SQL. This can be done using a combination of the TopPercent and Tail MDX functions.
For example, say you want to find the 25th percentile over a [Date].[Calendar Month] dimension attribute by the [Measures].[Avg Daily Census] (I work in health care) measure. You could use the following query to do this.
WITH
MEMBER [Measures].[25th Percentile] AS
(
Tail(
TopPercent(
[Date].[Calendar Month].[Calendar Month],
100 - 25,
[Measures].[Avg Daily Census]
)
).Item(0),
[Measures].[Avg Daily Census]
)
SELECT
[Measures].[25th Percentile] ON 0
FROM [Census]
This query uses TopPercent to find the top 75 percent of values along the [Calendar Month] dimension attribute, finds the member with the lowest value along that set, and then evaluates the measure at that member.
Now, if you want to generate the entire set of percentile values, you can use a sequence utility dimension (just a dimension containing numbers), or you could create a custom percentile dimension containing 0-99. The following query would generate the values of the measure over all percentages.
WITH
MEMBER [Measures].[Percentile] AS
(
Tail(
TopPercent(
[Date].[Calendar Month].[Calendar Month],
100 - [Sequence].[Ones].CurrentMember.MemberValue,
[Measures].[Avg Daily Census]
)
).Item(0),
[Measures].[Avg Daily Census]
)
SELECT
[Measures].[Percentile] ON 0,
[Sequence].[Ones].&[0] : [Sequence].[Ones].&[99] ON 1
FROM [Census]
However, if you are trying to evaluate percentiles at the grain of the fact table, then I believe you will either need to pre-calculate the percentile values for each fact row or add a degenerate dimension and use the method above.
I want to create a barchart with a bar for each month and some measure.
But i also want to filter on a range of day which might not completly overlap some of the month.
When that happen I would like the aggregate count for those month to only aggregat over the days that fall in my date range not get the aggregate for the whole month.
Is that possible with MDX and if it is how should the request look like?
Create a second time dimension, using a virtual dimension of the original dimension. Use one dimension in the WHERE and another in the SELECT.
This often happens anyway if some people want 'Business Time' of quarters and periods, and others prefer months. Or if you have a financial year which runs April-April.
You can use subselect. You can find more information on this page and this page:
When a member is specified in the axis clause then that member with
its ascendants and descendants are included in the sub cube space for
the subselect; all non mentioned sibling members, in the axis or
slicer clause, and their descendants are filtered from the subspace.
This way, the space of the outer select has been limited to the
existing members in the axis clause or slicer clause, with their
ascendants and descendants as mentioned before.
Here is an example:
SELECT { [Customer].[Customer Geography].[Country].&[Australia]
, [Customer].[Customer Geography].[Country].&[United States]
} ON 1
, {[Measures].[Internet Sales Amount], [Measures].[Reseller Sales Amount]} ON 0
FROM ( SELECT {[Customer].[Customer Geography].[Country].&[Australia]
, [Customer].[State-Province].&[WA]&[US]} ON 0
FROM [Adventure Works]
)
The result will contain one row for Autralia and another one for the United States. With the subselect, I restricted the value of United Stated to the Washington state.
One way I found to do it with Mondrian is as follow
WITH MEMBER [Measures].[Units Shipped2] AS
SUM
(
{
exists([Store].[Store Country].currentmember.children,{[Store].[USA].[WA],[Store].[USA].[OR]})
},[Measures].[Units Shipped]
)
MEMBER [Measures].[Warehouse Sales2] AS
SUM
(
{
exists([Store].[Store Country].currentmember.children,{[Store].[USA].[WA],[Store].[USA].[OR]})
},[Measures].[Warehouse Sales]
)
SELECT
{[Measures].[Units Shipped2],[Measures].[Warehouse Sales2]} ON 0,
NON EMPTY [Store].[Store Country].Members on 1
FROM [Warehouse]
I am not sure if the filtering will be done in SQL like below and give good performance or be run locally
select Country, sum(unit_shipped)
where state in ('WA','OR' )
group by Country