0
votes

I have 4 separate dimensions I'm interested in: ( A, B, C date ). Each dimension has multiple attribute hierarchies. Each dimension theoretically maps to each other. C -> B -> A. In other words, multiple members of B map to a single member in A and multiple members of C map to a single member of B.

Originally I had the following query which worked

SELECT 
(
    [Measures].[Count]
)
ON COLUMNS,
(
    [A].[Id].[Id].MEMBERS,
    FILTER
    (
        [A].[Name].[Name].MEMBERS, 
        LEFT([A].[Name].CURRENTMEMBER.NAME, 4) <> "test"
    ),
    [A].[Start].[Start].MEMBERS,
    [A].[Owner].[Owner].MEMBERS
)
ON ROWS
FROM 
(
    SELECT 
    (
        {[A].[Start].&[2020-05-10] : [A].[Start].&[2020-05-25]}
    )
    ON COLUMNS 
    FROM [Model]
)
WHERE
(
    {[date].[date].&[2020-05-10] : [date].[date].&[2020-05-25]},
    {[B].[End].&[2020-05-25]:NULL},
    [A].[Product].&[ASDF]
)

The output I was getting looked as follows:

  A.id  |  A.Name  |  A.Owner  |  Count 
----------------------------------------
   1    |     A    |    asdf   | (null)
   2    |     B    |    asdf   |   23
   3    |     C    |    asdd   | (null)
   4    |     D    |    asdf   | (null)
   5    |     E    |    qwer   |  5067
   6    |     F    |    adfd   | (null)
   7    |     G    |    wert   | (null)
  ...   |    ...   |    ....   |   ...
  25    |     Y    |    werd   | (null)

As you can see there are a lot of nulls in the data.

I now have additional requirement to filter only to "Enabled" members of the B.id hierarchy. So in the WHERE clause I added the following line: [B].[Status].&[Enabled]. This did not change my output but I know it should because I have to table that I need mocked up in PowerBI and this condition eliminates a few members from the A.id hierarchy.

Tha new output should look something like this:

  A.id  |  A.Name  |  A.Owner  |  Count 
----------------------------------------
   2    |     B    |    asdf   |   23
   4    |     D    |    asdf   | (null)
   5    |     E    |    qwer   |  5067
   7    |     G    |    wert   | (null)
  ...   |    ...   |    ....   |   ...
  25    |     Y    |    werd   | (null)

As you can see, some nulls should still be there because they have "Enabled" B.Id members mapped to them.

I then tried to add [B].[id].[id].MEMBERS and [B].[Status].[Status].MEMBERS on the rows to see what the relationship is and why certain members of A.id are not being dropped. I did that as follows:

(
    [A].[Id].[Id].MEMBERS,
    FILTER
    (
        [A].[Name].[Name].MEMBERS, 
        LEFT([A].[Name].CURRENTMEMBER.NAME, 4) <> "test"
    ),
    [A].[Start].[Start].MEMBERS,
    [A].[Owner].[Owner].MEMBERS,
    [B].[id].[id].MEMBERS,
    [B].[Status].[Status].MEMBERS
)
ON ROWS

But this showed every single member of A mapped with every single member of B. Basically a crossjoin. This is not what I need. Like I mentioned, there are unique members in B that map to one member in A. I did a lot of googling and came across a LINKMEMBER() function but this does not seem to work for the implementation I need. Any help or advice is appreciated.

The current query I am running is below. I have tried adding the commented [B].[Status].&[Enabled] to both the WHERE clause and ON ROWS but it was giving me the same results as always. I also tried to use the FILTER function and filter to only [B].[Status].CURRENTMEMBER.NAME = "Enabled" but that produced an empty table with no output.

SELECT 
(
    [Measures].[Count]
)
ON COLUMNS,
ORDER( 
    (
    --[B].[Status].&[Enabled],
    [A].[Id].Children,
    FILTER
    (
        [A].[Name].Children, 
        LEFT([A].[Name].CURRENTMEMBER.NAME, 4) <> "test"
    ),
    [A].[Start].Children,
    [A].[Owner].Children
    ),
    [A].[Start].CurrentMember.Member_Key,
    BASC
    )
ON ROWS
FROM 
(
    SELECT 
    (
        {[A].[Start].&[2020-05-21] : [A].[Start].&[2020-05-27]}
    )
    ON COLUMNS 
    FROM [Model]
)
WHERE
(
    {[date].[date].&[2020-05-21] : [date].[date].&[2020-05-27]},
    --[B].[Status].&[Enabled],
    [A].[Product].&[ASDF]
)

Im fairly new to MDX so I apologies for the extensive explanation.

1

1 Answers

0
votes

Welcome to Stackoverflow and MDX. The problem you are facing is address by using non empty. In MDX if you write (DimA.Attribute1.members,DimB.Attribute1.members), it means you are asking for a cross join. To ensure that only those combination are returned that are valid you have to use non empty. Try your modified query below

SELECT 
(
    [Measures].[Count]
)
ON COLUMNS,
non empty(
    [A].[Id].[Id].MEMBERS,
    FILTER
    (
        [A].[Name].[Name].MEMBERS, 
        LEFT([A].[Name].CURRENTMEMBER.NAME, 4) <> "test"
    ),
    [A].[Start].[Start].MEMBERS,
    [A].[Owner].[Owner].MEMBERS
)
ON ROWS
FROM 
(
    SELECT 
    (
        {[A].[Start].&[2020-05-10] : [A].[Start].&[2020-05-25]}
    )
    ON COLUMNS 
    FROM [Model]
)
WHERE
(
    {[date].[date].&[2020-05-10] : [date].[date].&[2020-05-25]},
    {[B].[End].&[2020-05-25]:NULL},
    [A].[Product].&[ASDF],[B].[Status].&[Enabled]
)

One thing that needs to be remembered is that this happens we you are using attribute of diffrent dimensions, if you have the same dimensions its handled automatically. Example (Dim1.attribute1.members, Dim1.attribute2.members), This will only returns datapoints that exist.

Try the Query below.

SELECT 
(
    [Measures].[Count]
)
ON COLUMNS,
([B].[Status].&[Enabled],
    [A].[Id].[Id].MEMBERS,
    FILTER
    (
        [A].[Name].[Name].MEMBERS, 
        LEFT([A].[Name].CURRENTMEMBER.NAME, 4) <> "test"
    ),
    [A].[Start].[Start].MEMBERS,
    [A].[Owner].[Owner].MEMBERS
)
ON ROWS
FROM 
(
    SELECT 
    (
        {[A].[Start].&[2020-05-10] : [A].[Start].&[2020-05-25]}
    )
    ON COLUMNS 
    FROM [Model]
)
WHERE
(
    {[date].[date].&[2020-05-10] : [date].[date].&[2020-05-25]},
    {[B].[End].&[2020-05-25]:NULL},
    [A].[Product].&[ASDF]
)