Filtering a SET with two dimensions - ssas

I have a fact table say WhsFactJob where we have CreatedTimeKey and InProgressTimeKey and I have a measure where Job Count.
I am trying to create a Calculated measure which will fetch me the job count whose CreatedTimeKey falls between 1(1:00 AM) and 2(2:00 AM) and InProgressTimeKey also falls with the same 1(1:00 AM) and 2(2:00 AM).
I tried to use SUM and Except, But it errors out saying Except has to use the same hierarchy.( CreatedTimeKey and InprogressTime Key are two seperate dimensions.
Any suggestions would help.
Here is the MDX example I am trying out.
WITH
MEMBER [Measures].[Sum] AS
SUM(
EXCEPT(
{[Created Time].[Hour].&[0]:[Created Time].[Hour].&[14]},
{[In Progress Time].[Hour].&[0]:[In Progress Time].[Hour].&[14]}
)
,[Measures].[Job Count]
)
SELECT
[Measures].[Sum] ON 0
FROM [Cube]

I'm not clear why you're using EXCEPT. How about this:
SUM
(
CROSSJOIN(
{[Created Time].[Hour].&[0]:[Created Time].[Hour].&[14]},
{[In Progress Time].[Hour].&[0]:[In Progress Time].[Hour].&[14]}
)
,[Measures].[Job Count]
)

I think you can get rid of the exception by cross-joining each set to members from the other set: not sure if the result of the query will be useful though - currently I'm unable to test the following:
The dimensionality of the two sets of tuples within the EXCEPT function should now be the same:
WITH
MEMBER [Measures].[Sum] AS
SUM(
EXCEPT(
{[Created Time].[Hour].&[0]:[Created Time].[Hour].&[14]}
*[In Progress Time].[Hour].[Hour].MEMBERS
, [Created Time].[Hour].[Hour].MEMBERS
*{[In Progress Time].[Hour].&[0]:[In Progress Time].[Hour].&[14]}
)
,[Measures].[Job Count]
)
SELECT
[Measures].[Sum] ON 0
FROM [Cube];

Related

MDX name set not working in calculated member

I have a named set like this :
(
[DimDate].[Hierarchy].currentmember.lag(1)
,
[Measures].[Fact Transaction Count]
)
This code give me count of transaction of yesterday current member. now I want to use it to calculate daily growth. some thing like this :
(
([Measures].[Fact Transaction Count] - GetPreviousTransactionValueDate.Item(0).Item(0)) / GetPreviousTransactionValueDate.Item(0).Item(0)
) * 100
when use it in SSMS I can get output but when I send it to SSDT I get a Null value for all hierarchy.
this code give me output :
with member measures.GetPreviousTransactionValueDate as
(
[DimDate].[Hierarchy].currentmember.lag(1)
,
[Measures].[Fact Transaction Count]
)
member measures.Roshd as
(
([Measures].[Fact Transaction Count] - measures.GetPreviousTransactionValueDate) / measures.GetPreviousTransactionValueDate) * 100
)
select non empty( measures.Roshd) on columns,
non empty([DimDate].[Hierarchy].[Month]) on rows
from [Cube]
I want to only use named Set not another calculated member for this topic. any help?
Finally I found that my way is wrong. because sets works on dimensions not use for creating a calculated member.

MDX where clause in subquery does not slice cube - how to understand?

This query gives me sales of one store:
select
[measures].[sales] on 0
from [MyCube]
where [store].[store].[042]
However, if I move the slicer to inside of the subquery, it gives me sales of all stores.
select
[measures].[sales] on 0
from (select
from [MyCube]
where [store].[store].[042]
)
How to understand the mechanisms behind this difference?
This is also noted in this article, but without much explanation.
----EDIT----:
I tried various things and read around for a while. I'd like to add a question: is there a scenario in which the where clause in sub-select does filter the result?
This query gives me sales of all stores in state MI (store [042] belongs to MI):
select
[measures].[sales] on 0
from (select
[store].[state].[MI] on 0
from [myCube]
where [store].[store].[042]
)
Thinking of 'inner query only filters if the filtered dimension is returned on an axis', the theory is proved wrong if I do this:
select
[measures].[sales] on 0
from (select
[store].[state].members on 0
from [myCube]
where [store].[store].[042]
)
The sub-select still returns one state MI, but the outer query returns sales of all stores (of all states).
----EDIT 4/13----:
Re-phrasing the question in AdventureWorks cube with screenshot.
Query 1: sales of one store
Query 2: it returns sales of all stores if where clause is in the sub-select.
Query 3: the two answers I got suggested that we select the dimension in an axis - here is the result - we get all cities.
select
[measures].[sales] on 0
from (select
from [MyCube]
where [store].[store].[042]
)
The above query reduces the scope of stores just to the member [042]. Make note that sub-select is executed before the actual select. So, when it comes to the select, the engine just sees a cube which has all the members in all the dimensions; but only the member [store].[store].[042] in the store dimension. It's as if the cube has been kept intact every where else but sliced off on the Store dimension.
If you go a step ahead and add the store on to one of the axes, like
select
[measures].[sales] on 0,
[store].[store].members on 1
from (select
from [MyCube]
where [store].[store].[042]
)
you would see that although the member [All] appears in the output, it actually is just comprised of only one store.
In essence, the [All] is a special member which is calculated with respect to scope of the cube. It reflects the combined effect of all the members in the cube.
In SQL terms, it is similar to:
select sales, store as [All] from
(select sales, store from tbl where store = '042') tbl
Even though you see Sales----All, it is but a reflection of sales for store [042]
Here are some other good references concerning sub-select and slicer debate:
http://bisherryli.com/2013/02/08/mdx-25-slicer-or-sub-cube/
https://cwebbbi.wordpress.com/2014/04/07/free-video-on-subselects-in-mdx/
Chris Webb's video being located here:
https://projectbotticelli.com/knowledge/what-is-a-subselect-mdx-video-tutorial?pk_campaign=tt2014cwb
This should still leave an All member:
SELECT
[measures].[sales] ON 0
FROM
(
SELECT
FROM [MyCube]
WHERE
[store].[store].[042]
);
...but the member [All] of the Store hierarchy will only now be made up of [store].[store].[042].
You can see this by adding the Store hierarchy onto ROWS:
SELECT
[measures].[sales] ON 0,
[store].MEMBERS ON 1
FROM
(
SELECT
FROM [MyCube]
WHERE
[store].[store].[042]
);
This is the AdvWorks version similar to the reference in your question:
SELECT
{[Measures].[Order Count]} ON 0
,[Subcategory].MEMBERS ON 1
FROM
(
SELECT
{
[Subcategory].[Subcategory].&[22]
} ON 0
FROM [Adventure Works]
);
It returns the member from the sub-select and the All member adjusted to take account of the subselect:
In the references article why is the [All] less than the sum of the other two - this is not down to the subselect but is in connection with the measure that he has chosen [Measures].[Order Count] which is a distinct count. If you take away the subselect you see exactly the same behaviour of the All member being less than the sum of the other subcategory members (I've marked the point at which the total of the parts becomes higher than the All member):
SELECT
{[Measures].[Order Count]} ON 0
,Order
(
[Subcategory].MEMBERS
,[Measures].[Order Count]
,bdesc
) ON 1
FROM [Adventure Works];
Order Count: on 1 order there might be several Product Subcategories - hence this behaviour.
Edit
This query of yours:
select
[measures].[sales] on 0
from (select
[store].[state].members on 0
from TestCube //<< added this!
where [store].[store].[042]
)
This inner script is not valid? Using the same dimension on an axes and the WHERE clause is not valid:
select
[store].[state].members on 0
from TestCube
where [store].[store].[042]
Edit2
An mdx script returns a cube, which may be sliced or not sliced, but nevertheless it returns a cube. The WHERE clause is used to slice the cube that is returned. If we were using a third party tool then the dimension added to the WHERE clause would go into a combobox - with say Cliffside selected. BUT the user could effectively select Ballard from that combobox - it is just a slicer. The WHERE clause is not changing the cube that is returned by the mdx script, it is just affecting what is displayed in the cellset.
WHERE is valid within a subselect. It is part of the definition:
https://msdn.microsoft.com/en-us/library/ff487138.aspx
I've never found a use case for a subselect's WHERE clause.
Edit3
This link will explain things:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/ccb66ac3-0f9a-4261-8ccc-b6ecc51b6f07/is-where-clause-pointless-inside-a-subselect?forum=sqlanalysisservices
As Darren gosbell says in the answer to this question:
https://msdn.microsoft.com/en-us/library/ff487138.aspx it says that:
The WHERE clause does not filter the subspace.

SSAS Calculated Member for measures that have the same Dimension

I am trying to create a calculated measure that subtracts measures that are in different groups, but only if they have the same dimension member whatever that may be. (edit - essentially exclude UnknownMember numbers in the subtraction)
I have tried using Scope:
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField] as NULL;
SCOPE([Dimension1].[DimensionField1].MEMBERS);
[Measures].[CalcField] = [Measures].[a] - [Measures].[b];
END SCOPE;
I have also tried using a Tuple without success:
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField]
AS ([Measures].[a] - [Measures].[b], [Dimension1].[DimensionField1]);
But I think there is something fundamental that I am missing
Edit
col a b dimension
1. 9 0 x
2. 0 2 x
3. 1 5 null
If you aggregate those rows I want the answer 7 not 5
Using a simple CASE WHEN works if the dimensions in use, but otherwise it blindly subtracts everything again
CASE
WHEN [Dimension1].[DimensionField1] IS [Dimension1].[DimensionField1].UnknownMember THEN 0
ELSE [Measures].[a] - [Measures].[b]
END
Using Aggregate works at the high level, but then when I use the Dimension I get no per member results
Aggregate(
EXCEPT(
[Dimension1].[DimensionField1].Members, {[Dimension1].[DimensionField1].UnknownMember, [Dimension1].[DimensionField1].[All]}
),[Measures].[a])
-
Aggregate(
EXCEPT(
[Dimension1].[DimensionField1].Members, {[Dimension1].[DimensionField1].UnknownMember, [Dimension1].[DimensionField1].[All]}
),[Measures].[b])
Workaround Solution
I am sorry if I was not clear on my problem, but I have ended up solving this problem by putting the data I need in at the ETL stage rather than calculating it in the Cube
Did you try either Summing or Aggregating your second snippet?
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField]
AS
Sum(
[Measures].[a] - [Measures].[b],
[Dimension1].[DimensionField1]
);
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField]
AS
Aggregate(
[Measures].[a] - [Measures].[b],
[Dimension1].[DimensionField1]
);
With Member [Measures].[CalcField] as [Measures].[a] - [Measures].[b]
Select [Measures].[CalcField]
on columns,
[Dimension1].[DimensionField1].MEMBERS
on rows
from [cube]

The MDX function CURRENTMEMBER failed because the coordinate for the 'Date' attribute contains a set

I'm trying to run this query:
select [Dim Date].[Date] on ROWS,
{[Measures].[Available Time Net],[Measures].[Logged On Time Net]} on columns
from [OTS Agent Time Net Data]
where {[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]}
I want to get the measures that exist in the where clause, but I also want to show the dates on the rows. I keep getting an error.
Why not just add the set directly to the ROWS ?
SELECT
NON EMPTY
{
[Dim Date].[Date].&[08/01/2014] : [Dim Date].[Date].&[12/31/2014]
} ON ROWS
,{
[Measures].[Available Time Net]
,[Measures].[Logged On Time Net]
} ON COLUMNS
FROM [OTS Agent Time Net Data];
You cannot use the same hierarchy ([Dim Date].[Date]) both on one axis and in the slicer (MDX tutorial); I guess using a sub-query would be fine for your example:
select
[Dim Date].[Date] on ROWS,
{[Measures].[Available Time Net],[Measures].[Logged On Time Net]} on columns
from (
select {[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]} on 0
from [OTS Agent Time Net Data]
)
Hope that helps.
(edit: using a named-set or using the slicer content right in the axis - see other responses - is a bit different because the request is filtering on a range of days but select [Dim Date].[Date] does not necessarily displays days; that could for example be the 'All' of the hierarchy of [Dim Date].[Date])
I agree with Marc's answer and that's probably the best way to do it. But there is one more way to do it, which doesn't need subselect, by making use of named sets.
with set DateRange AS
{[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]}
select NON EMPTY DateRange on ROWS,
{[Measures].[Available Time Net],[Measures].[Logged On Time Net]} on COLUMNS
from [OTS Agent Time Net Data]
EDIT
As per your request, if you want to additionally filter by time, here's one way to proceed. Replace the defenition of set DateRange with the below:
with set DateRange AS
EXISTS({[Dim Date].[Date].&[08/01/2014]:[Dim Date].[Date].&[12/31/2014]}
,[Dim Time].[Time].&[1930]
, "Time Net"
)
Few things which you need to fill in here..
Assuming time dimension's hierarchy to be [Dim Time].[Time]. Please replace with the actual name along with the member's format(Assumed it to be &[1930]
Also, Time Net is the measure group name to which the measures [Measures].[Available Time Net] and [Measures].[Logged On Time Net] belong to. Again, replace with original name.

Filtering dimensions in MDX inside a SUM

I am new to MDX expressions and I am trying to create one that sums the value of a given measure filtered by dimensions.
In my database I have several different dimensions that have the same name: "Answer". To sum them up, I have created the query below:
WITH MEMBER Measures.Total as SUM ({[Activity].[Activity].&[14], [Activity][Activity].&[22]},
[Measures].[Activity time])
SELECT NON EMPTY [Measures].[Total] on COLUMNS from [My Analytics]
This query works, however I had to use the "&[14]" and "&[22]" statments that correspond to two different "Answer" dimensions.
Since I have more than two dimensions with the same name, is there a way to rewrite the query above in a way that I would select all these dimensions without having to add their unique ID? For example, I would re-write the query as something like this:
WITH MEMBER Measures.Total as SUM ({[Activity].[Activity].&["Answer"]},
[Measures].[Activity time])
SELECT NON EMPTY [Measures].[Total] on COLUMNS from [My Analytics]
Is this possible?
Thanks!
You can use the Filter function as following:
with
set [my-answers] as
Filter( [Activity].[Activity].members,
[Activity].[Activity].currentMember.name = 'Answer'
)
member [Measures].[Total] as Sum( [my-answers] )
...