select data from olap MDX query - ssas

Please help to understand how MDX query works.
I have connected to cube using excel and construct a mdx query. In short finally I need to get the table like this:
12.01.2015
+-------+-------+-------+-----+-------+------
| 00:00 | 01:00 | 02:00 | ... | 23:00 | TOTAL
--------+-------+-------+-------+-----+-------+------
Ivan | null | 3 | null | ... | 12 | 38
Pert | 3 | 8 | null | ... | null | 125
Sidor |
We see the Date, Time (hour), FIO (Ivan, Petr etc) and values.
The cube has dimensions: Dim Date, Dim Hour, Dim Users
I trying to get MDX query from excel but I cant understand how to modify it to get result I need. Here is the request (formatted):
SELECT NON EMPTY
CrossJoin(
Hierarchize(
DrilldownMember(
{
{
DrilldownMember(
{
{
DrilldownLevel
(
{[Dim Date].[Даты YMD].[All]}
)
}
},
{[Dim Date].[Даты YMD].[Year Name].&[2015]}
)
}
},
{[Dim Date].[Даты YMD].[Year Name].&[2015].&[5]}
)
),
Hierarchize(
{
DrilldownLevel(
{[Dim Hour].[Hour Key].[All]}
)
}
))
DIMENSION PROPERTIES PARENT_UNIQUE_NAME,
[Dim Date].[Даты YMD].[Date Key].[Month Name],[Dim Date].[Даты YMD].[Date Key].[Year Name] ON COLUMNS ,
NON EMPTY
Hierarchize(
{
DrilldownLevel(
{[Dim Users].[FIO].[All]}
)
}
)
DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON ROWS FROM
(
SELECT ({[Dim Date].[Даты YMD].[Year Name].&[2015].&[5]}
)
ON COLUMNS
FROM [Dwh Sorting])
WHERE ([Measures].[Fact Table Count]) CELL PROPERTIES VALUE,
FORMAT_STRING,
LANGUAGE,
BACK_COLOR,
FORE_COLOR,
FONT_FLAGS
It gets data for May 2015. My goal is to get a long table (with a lot of columns) like I showed. With one or more months.

Excel code that is autogenerated adds a lot of extra "bits".
Getting rid of the extra bits I'm guessing at something like the below. This script should give you lots of columns - assuming data for every hour in 2015 you should end up with 24 columns for every day in 2015!
The reason I say "guessing" as we do not know the hiearchical structure of your cube:
SELECT
NON EMPTY
Descendants
(
[Dim Date].[Даты YMD].[Year Name].&[2015]
,[Dim Date].[Даты YMD].[Date] //<<this assumes there is a level in Dim date called Date
)
*
{[Dim Hour].[Hour Key].MEMBERS} ON COLUMNS
,NON EMPTY
[Dim Users].[FIO].MEMBERS ON ROWS
FROM [Dwh Sorting]
WHERE
[Measures].[Fact Table Count];
If you need just the hours for a range of dates then try the : operator. You will not need to apply the Descendants function in this case:
SELECT
NON EMPTY
(
[Dim Date].[Даты YMD].[Date Key].[2014-01-02]
:
[Dim Date].[Даты YMD].[Date Key].[2015-02-10]
)
*
{[Dim Hour].[Hour Key].MEMBERS} ON COLUMNS
,NON EMPTY
[Dim Users].[FIO].MEMBERS ON ROWS
FROM [Dwh Sorting]
WHERE
[Measures].[Fact Table Count];

Related

MDX: Distinct Count of members summarized by another dimension

From my cube, I am trying to get a distinct count of all non-empty [ID].[FullID]s but summarized by [Underlying].
I know that, for example, there are two IDs for [Underlying].[Underlying1] at this particular WHERE slice and I can see this by running the below MDX query, which clearly gives me a row for each (but a zero count?):
Results:
Underlying | FullID | CountOf
------------------------------
Underlying1 | ID1 | 0
Underlying1 | ID2 | 0
...
Code:
WITH
MEMBER CountOf AS
DistinctCount([ID].[FullID].Children)
SELECT
NON EMPTY {[Underlying].Children * [ID].[FullID].Children
} ON ROWS,
NON EMPTY {CountOf
} ON COLUMNS
FROM [MyCube]
WHERE ([Time].&[2018-11-27T00:00:00],
[Factor].[FactorName].[FACTOR1],
[Factor].[FactorType].[FACTORTYPE1]
[Location].[Location1]
)
However when I remove the * [ID].[FullID].Children I don't get what would like:
What I want:
Underlying | CountOf
---------------------
Underlying1 | 2
...
What I get:
Underlying | CountOf
---------------------
Underlying1 | 24
...
There is clearly something else going on here to give me a 24 count, but I cannot figure it out...
You are getting 24 because you measure is counting the members in [ID].[FullID].Children. What i understand is that you want to count the number of [ID].[FullID] who have a fact value availabe against them for [Underlying].Children. So your code should be like this
WITH
MEMBER CountOf AS
Count(
nonempty(([Underlying].currentmember,[ID].[FullID].Children),
[Measures].[ConnectingMeasure])
)
SELECT NON EMPTY {[Underlying].Children } ON ROWS,
NON EMPTY {CountOf} ON COLUMNS
FROM [MyCube]
WHERE ([Time].&[2018-11-27T00:00:00],[Factor].[FactorName].[FACTOR1],
[Factor].[FactorType].[FACTORTYPE1],[Location].[Location1]
)
Here is a sample of what you want to do in adventureworks. I am trying to count all Promotion, that are present for a product based on the internet sales data.
WITH
MEMBER CountOf AS
count(nonempty( ([Product].[Product].currentmember, [Promotion].[Promotion].children) ,[Measures].[Internet Sales Amount]))
SELECT
NON EMPTY {CountOf} ON COLUMNS,
NON EMPTY {
([Product].[Product].Children )
} ON ROWS
FROM [Adventure Works]
//Base query to understand what is counted
WITH
MEMBER CountOf AS
Count(nonempty( ([Product].[Product].currentmember, [Promotion].[Promotion].children) ,[Measures].[Internet Sales Amount]))
SELECT
NON EMPTY [Measures].[Internet Sales Amount] ON COLUMNS,
NON EMPTY {
([Product].[Product].Children,[Promotion].[Promotion].children )
} ON ROWS
FROM [Adventure Works]

Merge rows in mdx

I have some MDX:
SELECT
NON EMPTY {
[Dim Investigation Report].[ID].children *
[Dim Energy Object Full].[Name].children} ON ROWS,
NON EMPTY {[Measures].[ID Distinct Count]} ON COLUMNS
FROM [acts]
It returns:
003022 2604171226005 Object1 1
003022 2604171226005 Object2 1
How can I change the request to have result like this:
003022 2604171226005 Object1 Object2 1
Thank you.

Not allow any null values in resultset MDX

I want to exclude any rows where there is a null value in my MDX query. Sounds simple enough:
SELECT
NON EMPTY{
....
}
ON 0
etc...
However, one of my columns has values even though the other ones only contain null vales.
Example:
Area | ComputerSales | Areadirector
WA (Null) Steve
NY 21312 Mary
How do I remove the first row, where there is a (null) value?
You could use HAVING
SELECT
{
[Measures].[Computer Sales]
,[Measures].[Areadirector]
} ON 0
,[AreaDimension].[Area].[Area] HAVING
(NOT
IsEmpty([Measures].[Computer Sales])) ON 1
FROM [YourCube];
Or make the set in a WITH clause first:
WITH
SET [S] AS
NonEmpty
(
[AreaDimension].[Area].[Area]
,[Measures].[Computer Sales]
)
SELECT
{
[Measures].[Computer Sales]
,[Measures].[Areadirector]
} ON 0
,[S] ON 1
FROM [YourCube];
Second approach is probably more efficient.
You can use for example FILTER and ISEMPTY function
SELECT
[Measures].[Fac Count] on 0,
FILTER(
[Time].[Date Key].children,
NOT ISEMPTY([Measures].[Fac Count])
)
on 1
FROM
[Test]
this simple query returns only date keys that Fac Count measure has non empty value.

MDX Using multiple date dimensions

What I want to do is generate a report containing an overview of gains and losses (of contracts). For example:
Year | contract_gains | contract_losses
_______________________________________
2015 | 10 | 2
2016 | 15 | 4
Showing the gains is quite easy because I can just count distinct contracts (which is the aggregator for the measure value) with a start period.
SELECT
{[contract_start_date].[year].MEMBERS}
ON ROWS,
{[Measures].[value]}
ON COLUMNS
FROM Cube
Showing the losses seperately is also easy because I can do the same with the second date dimension.
SELECT
{[contract_end_date].[year].MEMBERS}
ON ROWS,
{[Measures].[value]}
ON COLUMNS
FROM Cube
But what I want to do is generate a report containing both of the values in a single report. Sadly I have no idea how I can do this.
A little slow method, going cell by cell. Does this work for you -
WITH MEMBER [Measures].contract_losses AS
(
GENERATE
(
[contract_start_date].[year].CURRENTMEMBER,
FILTER
(
[contract_end_date].[year].MEMBERS,
CStr([contract_start_date].[year].CURRENTMEMBER.MEMBER_VALUE) = CStr([contract_end_date].[year].CURRENTMEMBER.MEMBER_VALUE)
)
).ITEM(0)
,
[Measures].[value]
)
MEMBER [Measures].contract_gains AS
[Measures].[value]
SELECT
NON EMPTY {[contract_start_date].[year].MEMBERS}
ON ROWS,
{[Measures].contract_gains, [Measures].contract_losses}
ON COLUMNS
FROM [Cube]

Fetching Previous Member while using order function in MDX

I have a mdx query which returns "productCode" and "Product share of total Sales" as a result.Also i need that query be sorted on "Product share of total Sales" (Decs)
So I came up with following MDX Query
WITH MEMBER [Measures].[Contribution] AS
Format(
IIF(
IsEmpty([Measures].[Detail_Net_Sales]),
0,
[Measures].[Detail_Net_Sales]
)/
[Measures].[SumTotalPayable]
)
SELECT
{[Measures].[Contribution]}
ON COLUMNS,
Order(
[DIMProduct].[ProductCode].[ProductCode].AllMEMBERS,
[Measures].[Contribution],
BDESC
)
ON ROWS
FROM [Model] }
the problem is when i also want to have Previous Contribution for each productcode
i wrote down somthing like this :
WITH MEMBER [Measures].[Contribution] AS
Format(iif(IsEmpty([Measures].[Detail_Net_Sales]),0,[Measures] [Detail_Net_Sales])/[Measures].[SumTotalPayable] )
MEMBER [Measures].[test]
AS
([Measures].[Contribution], [DIMProduct].[ProductCode].CurrentMember.PrevMember)
SELECT { [Measures].[Contribution] ,[Measures].[test]} ON COLUMNS
, Order([DIMProduct].[ProductCode].[ProductCode].AllMEMBERS ,[Measures]. [Contribution],BDESC)ON ROWS
FROM [Model]
but the above code will return previous Contribution without desire order.
do you have any idea how can i fix this?
Edit :
I want to have the Contribution of the previous row base on my sort and also have the test measure base on my prior sort,like the below table:
ProductCode Contribution Test
----------- ------------ ----
123 17.56 null
332 17.30 17.56
245 16 17.30
656 15.90 16
but what i get is like this :
ProductCode Contribution Test
----------- ------------ ----
123 17.56 17.30
332 17.30 16
245 16 Null
656 15.90 17.30
WITH MEMBER [Measures].[Contribution] AS
Format(
IIF(
IsEmpty([Measures].[Detail_Net_Sales]),
0,
[Measures].[Detail_Net_Sales]
)/
[Measures].[SumTotalPayable]
)
SET SortedProducts AS
Order(
[DIMProduct].[ProductCode].[ProductCode].AllMEMBERS,
[Measures].[Contribution],
BDESC
)
MEMBER [Measures].[PrevContribution] AS
(SortedProducts.Item(
Rank([DIMProduct].[ProductCode].CurrentMember, SortedProducts) - 2)
.Item(0),
[Measures].[Contribution])
SELECT
{[Measures].[Contribution], [Measures].[PrevContribution]}
ON COLUMNS,
SortedProducts
ON ROWS
FROM [Model] }
Your definition of the test measure uses the order of members as defined in the cube (alphabetically, if you did not define a custom order). But you need the order by Contribution, so I defined that as a named set containing the members in this order. Then I mis-used the Rank function which gives you the position of a tuple in a set. As the rank of the first member is 1, and I use the Item function to get a tuple within the set - which starts numbering the tuples with zero -, and we have to go one member back, you need the - 2, and finally, we need another Item(0) to get a member from the tuple.