MDX,how to flatten the result of Descendants function - ssas

I have a hierarchy with 5 level,I use Descendants() to retrieve all lower level of a member.But i end up with a one column result where i like to have a result with one column for each level.So on each row i repeat the parent,grand parents etc of the current member.
WITH
MEMBER [Measures].[key] AS
[DimGLAcct].[MgtCOA].CurrentMember.UNIQUENAME
MEMBER [Measures].[level_] AS
[DimGLAcct].[MgtCOA].CurrentMember.level.ordinal
SELECT
{
[Measures].[key]
, [Measures].[level_]
, [Measures].[Actuals]
} ON COLUMNS,
{
Descendants(
[DimGLAcct].[MgtCOA].[Mparent5].&[MCOA].&[400000M - Total operating overhead expenses].&[440000M - Other expenses].&[441000M - Other expenses]
,
,SELF_AND_AFTER
)
} ON ROWS
FROM [Model];

I cannot quite suss out the names of your levels but it is ok to do the following in mdx:
WITH
MEMBER [Measures].[key] AS
[DimGLAcct].[MgtCOA].CurrentMember.UNIQUENAME
MEMBER [Measures].[level_] AS
[DimGLAcct].[MgtCOA].CurrentMember.level.ordinal
SELECT
{
[Measures].[key]
, [Measures].[level_]
, [Measures].[Actuals]
} ON COLUMNS,
[DimGLAcct].[LevelX]
*[DimGLAcct].[LevelY]
*[DimGLAcct].[LevelZ]
*[DimGLAcct].[LevelK]
ON ROWS
FROM [Model];
Each of the levels in your user hierarchy will have respective attribute hieraries - which are used in the above.

Related

MDX query - Subselect implementation - Select all values of a column except one

I have to implement a query with the following requirements.
1) I need to have multiple conditions(with AND,OR).
2) There are conditions where I need to exclude the records with a particular value.
SELECT {...} ON Columns, {...} ON ROWS
FROM
(SELECT {([Element1].[Value].&[98]&[002], [Element2].Value.&[Value1]),
([Element1].[Value].&[98]&[004], [Element2].Value.&[Value2]), ([Element1].[Value].&[98]&[005], [Element2].Value.NOTIN[value1, value2]), } ON Columns
FROM [CubeName])
I have mentioned NOTIN[value1,value2]) as I am unaware of how this can be implemented. I have to get all values except those mentioned. Please let me know if any one can provide a solution.
You would generally use the function EXCEPT to exclude some members from a set:
SELECT
{...} ON 0
, {...} ON 1
FROM
(
SELECT
EXCEPT(
[Element1].[Value].[Value].MEMBERS //<<name of the full set
,{ //<<the set to be excluded
[Element1].[Value].&[98]&[002],
[Element1].[Value].&[98]&[004],
[Element1].[Value].&[98]&[005]
} ON 0
FROM [CubeName]
);
The above could be expanded out to tuples but the first argument will need to be a cross-join:
SELECT
{...} ON 0
, {...} ON 1
FROM
(
SELECT
EXCEPT(
[Element1].[Hier1].[Hier1].MEMBERS
* [Element1].[Hier2].[Hier2].MEMBERS //<<name of the full set
,{ //<<the set to be excluded
([Element1].[Hier1].[Hier1].&[Value1],[Element1].[Hier2].[Hier2].&[Value1]),
([Element1].[Hier1].[Hier1].&[Value2],[Element1].[Hier2].[Hier2].&[Value2]),
([Element1].[Hier1].[Hier1].&[Value3],[Element1].[Hier2].[Hier2].&[Value3]),
} ON 0
FROM [CubeName]
);

MDX-Query - Query with to many rows. Set correct filter

I work on a problem with an MDX Query.
The cube contains models and serials (units) and should show all units in warranty for each year.
This is the a cube with this Dimensions/Measures:
CubeOverview
Now I would select all Serials which are in warranty for a special year.
The problem is that the whole Table v Dim Unit Model 4IB Test contains more than 50 Mio rows which results alsways to an QueryTimeout or sometimes to an MemoryException.
At the moment I have a MDX query (see below) which works if I select special model. But I need the filter to all models.
WITH
MEMBER [Measures].[QtyTotal] AS
[Measures].[QtyInWarranty] + [Measures].[QtyInExtension]
SELECT
NON EMPTY
{
[Measures].[QtyStdOut] ,[Measures].[QtyInExtension] ,[Measures].[QtyStdIn]
,[Measures].[QtyInWarranty] ,[Measures].[QtyTotal] ,[Measures].[SumStartWarranty]
} ON COLUMNS
,NON EMPTY
{
crossjoin(
[v Dim Unit Model 4IB Test].[ModelUnitMapping].[Id Unit].Members
,[Dim Country].[Id Country].[Id Country].members
,[Dim Calendar].[Calendar].[Month Name4report].members
)
} ON ROWS
FROM
(
SELECT
{
[v Dim Unit Model 4IB Test].[model no short].[Model No Short].&[SampleModel]
} ON COLUMNS
FROM
(
SELECT
{
[Dim Calendar].[Calendar].[Year].&[2015]
} ON COLUMNS
FROM [InstalledBaseCS_Serial]
)
)
Does anybody knows a tip to update the query to get all units for one year (round about 4 Mio rows)?
If you're trying to return the results to a visible grid in MDXstudio or SSMS then it may be timing out because there is quite a bit to render.
If you use OPENQUERY or the CLR OLAP Extensions then try the following:
Do not return the results to the screen but INSERT results into a table.
Simplifiy your script by taking away the custom measure. This can easily be calculated later as it is trivial: I have a feeling it is slowing down ssas.
Script
SELECT
NON EMPTY
{
[Measures].[QtyStdOut]
,[Measures].[QtyInExtension]
,[Measures].[QtyStdIn]
,[Measures].[QtyInWarranty]
,[Measures].[SumStartWarranty]
} ON 0
,NON EMPTY
[v Dim Unit Model 4IB Test].[ModelUnitMapping].[Id Unit].Members
*[Dim Country].[Id Country].[Id Country].members
*[Dim Calendar].[Calendar].[Month Name4report].members
ON 1
FROM
(
SELECT
[v Dim Unit Model 4IB Test].[model no short].[Model No Short].&[SampleModel] ON 0
FROM
(
SELECT [Dim Calendar].[Calendar].[Year].&[2015] ON 0
FROM [InstalledBaseCS_Serial]
)
);

MDX Filtering dimension members with result of other dimension

I would like to filter a dimension for cube security with some information that are in another dimension.
So - I have a dimension which holds some account Responsible (Account Number and the initials on the one responsible) and another Dimension with all accounts.
I would like to make sure, that a person only can see movements on the accounts on which they are responsible.
I can make the filtering work like this:
SELECT
{} ON 0
,{
Exists
(
Filter
(
[Accounts].[Accounts].[AccountNo]
*
[AccountResponsible].[AccountResponsible].[AccountNo]
,
[Accounts].[Accounts].Properties("key")
=
[AccountResponsible].[AccountResponsible].Properties("key")
)
,[AccountResponsible].[Responsible].&[MSA]
)
} ON 1
FROM mycube;
the problem is, that there are two columns, and I can't use that in cube security. Is there a way to rewrite this, so that I actually get only one column with the members that the user are allowed to see?
Try using the Extract function:
SELECT
{} ON 0
,
EXTRACT(
{
Exists
(
Filter
(
[Accounts].[Accounts].[AccountNo]
*
[AccountResponsible].[AccountResponsible].[AccountNo]
,
[Accounts].[Accounts].Properties("key")
=
[AccountResponsible].[AccountResponsible].Properties("key")
)
,[AccountResponsible].[Responsible].&[MSA]
)
}
,[Accounts].[Accounts] //<<HIERARCHY YOU WISH TO EXTRACT
) ON 1
FROM mycube;

UNION multiple MDX queries in SSAS (powerpivot)

I have some sort of difficulties trying to join 2 MDX queries together. When running them separately they work fine. The script below
WITH
MEMBER [Measures].[ParameterCaption] AS
[Main_Incidents].[Priority].CurrentMember.Member_Caption
MEMBER [Measures].[ParameterValue] AS
[Main_Incidents].[Priority].CurrentMember.UniqueName
MEMBER [Measures].[ParameterLevel] AS
[Main_Incidents].[Priority].CurrentMember.Level.Ordinal
SELECT
{
[Measures].[ParameterCaption]
,[Measures].[# Incidents]
,[Measures].[%SLA]
} ON COLUMNS
,[Main_Incidents].[Priority].ALLMEMBERS ON ROWS
FROM [Model];
WITH
MEMBER [Measures].[ParameterCaption] AS
[Main_Incidents].[usr_directorate].CurrentMember.Member_Caption
MEMBER [Measures].[ParameterValue] AS
[Main_Incidents].[usr_directorate].CurrentMember.UniqueName
MEMBER [Measures].[ParameterLevel] AS
[Main_Incidents].[usr_directorate].CurrentMember.Level.Ordinal
SELECT
{
[Measures].[ParameterCaption]
,[Measures].[# Incidents]
,[Measures].[%SLA]
} ON COLUMNS
,[Main_Incidents].[usr_directorate].ALLMEMBERS ON ROWS
FROM [Model];
The most important bit for me is that I need the label column to show. So I want to UNION the 2 queries together so that the ParameterCaption captures values from "Priority" dimension and "Directorate" dimension....
Please someone help me to achieve this?
This is a bit complex, but definitely possible.
Union in MDX only works for members of the same hierarchy, so to achieve this we need to make the row members into Tuples that combine the two hierarchies. We can do this by cross joining each of the ALLMEMBERS sets to the [All] member for the other hierarchy. Then we just need to change the Parameter Caption, Value and Level to conditionally get the value from the appropriate hierarchy.
This could look something like the code below:
WITH
MEMBER [Measures].[ParameterCaption] AS
IIF([Main_Incidents].[Priority].CurrentMember.Level.Ordinal = 0, [Main_Incidents].[usr_directorate].CurrentMember.Member_Caption, [Main_Incidents].[Priority].CurrentMember.Member_Caption)
MEMBER [Measures].[ParameterValue] AS
IIF([Main_Incidents].[Priority].CurrentMember.Level.Ordinal = 0, [Main_Incidents].[usr_directorate].CurrentMember.UniqueName, [Main_Incidents].[Priority].CurrentMember.UniqueName)
MEMBER [Measures].[ParameterLevel] AS
IIF([Main_Incidents].[Priority].CurrentMember.Level.Ordinal = 0, [Main_Incidents].[usr_directorate].CurrentMember.Level.Ordinal , [Main_Incidents].[Priority].CurrentMember.Level.Ordinal)
SELECT
{
[Measures].[ParameterCaption]
,[Measures].[# Incidents]
,[Measures].[%SLA]
} ON COLUMNS
,{
[Main_Incidents].[Priority].ALLMEMBERS * [Main_Incidents].[usr_directorate].[All],
[Main_Incidents].[Priority].[All] * [Main_Incidents].[usr_directorate].ALLMEMBERS
} ON ROWS
FROM [Model];

Search AllMembers of User Hierarchy - for corresponding Set return a related members from upper and lower levels

We have a user hierarchy with 3 levels (Level1 being the upper level - Level3 the lower)
Using the FILTER function I state a string, this string could be within the member_name of any member from any (or several) of the levels. This returns a set.
I would then like all members from the hierarchy related to each item in the set; both upper and lower levels.
I've also tried (unsuccessfully) to include a column that is always Level2 in the results as a reference and also an ordering column.
WITH
MEMBER [Measures].[LevelName] AS
[DimensionX].[HierX].Level.Name
MEMBER [Measures].[LevelNumber] AS
[DimensionX].[HierX].Level.Ordinal
MEMBER [Measures].[MemName] AS //<<<<<not working as I want level 2 in the result set
[DimensionX].[HierX].currentmember.membervalue
SET [Set_Target] AS
{
FILTER(
[DimensionX].[HierX].AllMembers,
(
InStr(
1,
[DimensionX].[HierX].currentmember.name,
"jesus") <> 0
)
)
}
SELECT
// ORDER(
// Exists(
// [AttributeHierX].members,
// [Set_Target]
// ),
// [AttributeHierX].[AttributeHierX].MEMBERVALUE
// )
//*
ORDER(
DESCENDANTS(
[Set_Target],
[DimensionX].[HierX].[Level1],
SELF_BEFORE_AFTER
),
[Measures].[LevelNumber],
BASC
) as X
ON 1,
{
[Measures].[MemName],
[Measures].[LevelName],
[Measures].[LevelNumber]
} ON 0
FROM [CubeX]
I suppose a similar query on AdventureWorks delivers what you want:
WITH
MEMBER [Measures].[LevelName] AS
[Employee].[Employee Department].CurrentMember.Level.Name
MEMBER [Measures].[LevelNumber] AS
[Employee].[Employee Department].CurrentMember.Level.Ordinal
MEMBER [Measures].[MemName] AS
[Employee].[Employee Department].CurrentMember.Name
SET [Set_TargetEmp] AS
{
FILTER(
[Employee Department].AllMembers,
(
InStr(
1,
[Employee].[Employee Department].currentmember.name,
"WC4") <> 0
)
)
}
SELECT
{
[Measures].[MemName],
[Measures].[LevelName],
[Measures].[LevelNumber]
} ON 0,
Hierarchize(
Generate([Set_TargetEmp] as e,
Ascendants(e.Current)
+
Descendants(e.Current, e.Current.Level, SELF_AND_AFTER)
)
)
ON 1
FROM [Adventure Works]
I used Hierarchize to sort the result by hierarchy, as that seemed the most easy way for me to check the result. You may want to change that. As - in contrast to the Descendants method - Ascendants does not allow a set as the first argument, I used Generate to iterate along the set. Its default behavior (without a third argument of All), it eliminates duplicates, which I assumed is the behavior you need.