0

We use Excel from Office 365 with a SQL Server 2019 Tabular model

I have a "strange" behaviour of Excel Pivot regarding the level at which calculations are requested from DAX.

I create 3 simple (SQL Server) tables, MyDim, DimColour and MyFact

Base tables

There is an implicit hierachy (not enforced) between the BrandName and ItemName in the MyDim table.

I could not enforce this because nothing says that an Item can only belong to one brand.

I create a very basic measure to aggregate the fact although I don't really need it here

FactTotal := SUM(MyFact[FactValue])

And I also create 2 additional measures that are more interesting

LowestLevel :=
SWITCH (
    TRUE (),
    ISFILTERED ( 'MyDim'[ItemName] ), "Item",
    ISFILTERED ( 'MyDim'[BrandName] ), "Brand",
    "Neither Brand nor Item"
)

Lowest Level ALWAYS return a value, regardless of whether there are rows in the fact table.

LowestLevelButItem :=
SWITCH (
    TRUE (),
    ISFILTERED ( 'MyDim'[ItemName] ), BLANK (),
    ISFILTERED ( 'MyDim'[BrandName] ), "Brand",
    "Neither Brand nor Item"
)

LowestLevelButItem returns a value as long as we are not filtering on ItemName

Now, this is the behaviour which bothers us...

Open the cube in an Excel Pivot table, filter on colours Blue and Yellow

Result 1, ok

Result 1, ok

This is the right result. No problem here.

Add the measure LowestLevelButItem...

Result 2, unexpected

Result 2, Unexpected

Now, this is not the result we would like... I would not expect to see "Brand A" at all in this result

It shows that the measure displayed in D4 has been evaluated at a different level than D5 & D6.

D5 & D6 are evaluated at the Item level, as expected while D4 is evaluated at a higher level because there is no matching row at Item level...

Now, add the measure LowestLevel

Result 3, ok

Result 3, ok

Now, I understand this result.

Because LowestLevel ALWAYS returns a value, it makes Brand A / Item 1 visible, which forces evaluation of the measure LowestLevelButItem at the Item level, hence blank().

The problem I have is with the second result...

Question

How could I force the Pivot table to NOT return the Brand if there is no suitable Item underneath?

SSMS Behaviour

If I browse my cube in SSMS, I get the results I would expect, which is that my measures are always evaluated at the leaf level only and rows are not returned unless they have leaf level members.

SSMS Result 1, same

SSMS Result 1

SSMS Result 2

SSMS Result 2, ok unlike Excel

SSMS did not return a row for "Brand A" with no Item member

SSMS Result 3

SSMS Result 3

SQL Script to reproduce

CREATE TABLE MyDim(MyDimId      INT NOT NULL PRIMARY KEY
                  ,BrandName    VARCHAR(100) NOT NULL
                  ,ItemName     VARCHAR(100) NOT NULL
                  );

GO

-- TRUNCATE TABLE MyDim;
INSERT INTO MyDim(MyDimId, BrandName, ItemName)
  VALUES(1, 'Brand A', 'Item 1')
       ,(2, 'Brand B', 'Item 2')
       ,(3, 'Brand B', 'Item 3');
GO

CREATE TABLE DimColour(Colour VARCHAR(100) NOT NULL PRIMARY KEY);
GO

INSERT INTO DimColour(Colour)
  VALUES('Red')
      , ('Blue')
      , ('Yellow');

CREATE TABLE MyFact(MyDimId   INT NOT NULL
                   ,Colour    VARCHAR(100) NOT NULL
                   ,FactValue INT NOT NULL
                   ,PRIMARY KEY(MyDimId, Colour)
                   );
GO

-- TRUNCATE TABLE MyFact;
INSERT INTO MyFact(MyDimId, Colour, FactValue)
  VALUES(1, 'Red',    1)
      , (2, 'Blue',   2)
      , (3, 'Blue',   4)
      , (3, 'Yellow', 8);

MDX generated for Result 2 queries

  • By SSMS (producing the result I want)

SSMS MDX

  • Excel MDX

Excel MDX

Eric Mamet
  • 2,681
  • 2
  • 13
  • 43

1 Answers1

1

Just add the following IF clause to your measure:

LowestLevelButItem :=
IF(
  NOT(ISBLANK([FactTotal])),
  SWITCH (
    TRUE (),
    ISFILTERED ( 'MyDim'[ItemName] ), BLANK (),
    ISFILTERED ( 'MyDim'[BrandName] ), "Brand",
    "Neither Brand nor Item"
  )
)
GregGalloway
  • 11,355
  • 3
  • 16
  • 47
  • Interesting... I was just experimenting with this and you may have a point – Eric Mamet Dec 23 '21 at 13:34
  • Of course you could add a first SWITCH condition ISBLANK([FactTotal]) which returns BLANK() but I wanted to make my answer more generic and not assume all your measures were a SWITCH at the top level. – GregGalloway Dec 23 '21 at 13:39
  • Thanks for that, I need to do a fair amount of testing in our initial context, which is far more complicated... but you have given us HOPE! I'll report on the outcome – Eric Mamet Dec 23 '21 at 13:53
  • Glad to hear. Feel free to click the green checkmark if your question is answered – GregGalloway Dec 23 '21 at 13:59
  • Unfortunately, it does not really solve our problem because I think the issue is with the Excel behaviour rather than DAX. It looks like if Excel detects that the measure at the "item" level returns blank(), it does not return blank() but runs that measure at the "Brand" level. DAX answers the right answer but the question is wrong... – Eric Mamet Dec 23 '21 at 14:24
  • I have to explain that our "complicated" measure cheats in some cases and gathers numbers by eliminating the filter on the Brand Name itself, hence there is not a straight relationship to the presence of direct underlying facts... – Eric Mamet Dec 23 '21 at 14:25
  • I posted a similar request on Microsoft Q&A and was advised that Power BI does not present the same problem... which does not entirely help us because our users want to use Excel. https://learn.microsoft.com/en-us/answers/questions/674040/ssms-mdx-yes-excel-mdx-no.html?childToView=674718#answer-674718 – Eric Mamet Dec 26 '21 at 11:22
  • Maybe on your original question on Stack Overflow post your full DAX for your measures and we can look at it. – GregGalloway Dec 26 '21 at 12:57
  • I would also ask whether you want to turn off subtotals. If so go to the PivotTable Design tab and pop open the subtotals drop down and choose off for rows and columns. This WILL change the MDX generated. Also try different formats from the drop down beside it. – GregGalloway Dec 26 '21 at 13:00
  • 1
    Indeed turning off the totals gets rid of this undesired row – Eric Mamet Dec 30 '21 at 18:16