I would like to write an MDX query that only show values when a specific repeated dimesions are repeatid more tha one.
That is my mdx query:
SELECT
NON EMPTY { [Measures].[Value] } ON COLUMNS,
NON EMPTY { ([Dim Result].[Sample Number].[Sample Number].ALLMEMBERS
* [Dim Parameter].[IdParameter].[IdParameter].ALLMEMBERS ) } ON ROWS
FROM [Cube]
the result its like that:
Sample Number IdParameter Value
1 3 5
1 4 6
2 3 2
3 4 0
What i want is to get only repeated sample number values like this:
Sample Number IdParameter Value
1 3 5
1 4 6
And remove the other values that are not repeated
Sample Number IdParameter Value
2 3 2
3 4 0
I donĀ“t know how i can do this, it is posible?
I write the next mdx:
SELECT NON EMPTY {[Measures].[Recuento Fact Result]} ON COLUMNS,
NON EMPTY { [Dim Result].[Sample Number].[Sample Number] } ON ROWS
FROM ( SELECT ({ [Dim Parameter].[IdParameter].&[420] , [Dim Parameter].[IdParameter].&[20] } ) ON COLUMNS
FROM [cube])
the result is that:
Sample Number Recount Fact Result
1 1
2 2
3 2
4 1
What i want is get only the Sample number where the recount is biger than 1
thanks for your help
My approach would be to create a calculated member which would hold number of distinct non-empty members per SampleNumber. Then filter out those tuples where the above count is not greater than 1.
UNTESTED (not near my system)
WITH MEMBER [Measures].CntParametersPerSampleNumber as
DistinctCount(
NonEmpty(
[Dim Parameter].[IdParameter].CHILDREN,
([Dim Result].[Sample Number].CURRENTMEMBER, [Measures].[Value])
)
)
SELECT
NON EMPTY { [Measures].[Value] } ON COLUMNS,
NON EMPTY {
Filter(
(
[Dim Result].[Sample Number].[Sample Number].ALLMEMBERS
*
[Dim Parameter].[IdParameter].[IdParameter].ALLMEMBERS
), [Measures].CntParametersPerSampleNumber>1
)
} ON ROWS
FROM [Cube]
You seem to have two separate questions.
The second question can be answered using the HAVING clause:
SELECT
NON EMPTY
{[Measures].[Recuento Fact Result]} ON 0,
NON EMPTY
{[Dim Result].[Sample Number].[Sample Number]}
HAVING [Measures].[Recuento Fact Result] > 1
ON 1
FROM
(
SELECT
({
[Dim Parameter].[IdParameter].&[420]
, [Dim Parameter].[IdParameter].&[20]
}) ON 0
FROM [cube]
)
For you first question you should be able to use the Filter function iteratively to detect if sample number is repeated:
WITH
SET [OrderedSampleNums] AS
Order(
[Dim Result].[Sample Number].[Sample Number].ALLMEMBERS ,
[Dim Result].[Sample Number].CurrentMember.Caption,
BASC
)
SET [RepeatedSampleNums] AS
Filter(
OrderedSampleNums ,
OrderedSampleNums.Item(
OrderedSampleNums.CurrentOrdinal-1
).Caption = [Dim Result].[Sample Number].CurrentMember.Caption
)
SET [NonRepeatedSampleNums] AS
Except(
OrderedSampleNums
,RepeatedSampleNums
)
SELECT
NON EMPTY
{[Measures].[Value]} ON 0,
NON EMPTY
[NonRepeatedSampleNums]
*
[Dim Parameter].[IdParameter].[IdParameter].ALLMEMBERS
ON 1
FROM [Cube];
Not tested but I could try to prototype something against the AdvWorks cube to explore further?
Related
I am looking to filter the result set below such that I only show results where Dimension A Value 1 have a count of 1, regardless of the value of count for Dimension A Value 2
Dimension A Value 1 Dimension A Value 2
Entity ID Count Count
11 1
78 1
90 1
101 1
114 1
118 1
125 1
134 1
140 1
161 1
169 1
186 1 2
The filtered set would look like
Dimension A Value 1 Dimension A Value 2
Entity ID Count Count
11 1
78 1
90 1
101 1
118 1
125 1
140 1
161 1
169 1
186 1 2
the mdx is
WITH
SET [~COLUMNS] AS
{[Dimension A].[Dimension A].[Value 1], [Dimension A].[Dimension A].[Value 2]}
SET [~ROWS] AS
{[Entity].[Entity].[Entity ID].Members}
SELECT
NON EMPTY CrossJoin([~COLUMNS], {[Measures].[Count]}) ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [My Cube]
I've been playing around with Filter and NonEmpty but I'm new to MDX and my sql brain is hurting. I suppose this is probably trivial to someone with a lot of MDX under their belt but I'm failing. Be gentle this is my first question
You can try a HAVING clause:
WITH
SET [~COLUMNS] AS
{
[Dimension A].[Dimension A].[Value 1],
[Dimension A].[Dimension A].[Value 2]
}
MEMBER [Measures].[CountValue1] AS //<<<<this is new <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
(
[Measures].[Count],
[Dimension A].[Dimension A].[Value 1]
)
SELECT
NON EMPTY
CrossJoin(
[~COLUMNS]
, {[Measures].[Count]}
) ON COLUMNS,
NON EMPTY
[Entity].[Entity].[Entity ID].MEMBERS
HAVING [Measures].[CountValue1] = 1 //<<CHANGED TO NEW MEASURE
ON ROWS
FROM [My Cube];
If you can use HAVING rather than FILTER you will likely see a performance improvement - particularly if your scripts become more complex:
https://blog.crossjoin.co.uk/2006/01/04/the-having-clause/
Just to be complete the slower FILTER version would be this:
WITH
SET [~COLUMNS] AS
{
[Dimension A].[Dimension A].[Value 1],
[Dimension A].[Dimension A].[Value 2]
}
//>>>>>> following is new >>>>>>>>>>>>>>>>>>>>>
MEMBER [Measures].[CountValueNEW] AS
(
[Measures].[Count],
[Dimension A].[Dimension A].[Value 1]
)
SELECT
NON EMPTY
[~COLUMNS]
*{[Measures].[Count]}
ON 0,
NON EMPTY
FILTER(
[Entity].[Entity].[Entity ID].MEMBERS,
[Measures].[CountValueNEW] = 1
)
ON 1
FROM [My Cube];
Your query should be like
Select ([Dimension A].[AttributeHierarchy1].[AttributeHierarchy1],{[Measures].[Value1],[Measures].[Value2]}) on columns,
filter([Dimension B].[EntityID].[EntityID],[Measures].[Value1]=0)
on rows
from yourcube
However there can be an issue. For example your dimesnion has two values A and B, for a particular row , A,value1 =1 but B, Value1=0, this row will appear as A qulifies for it and B gets carried over.
Edit
Lets take an example I want to see Internet Sales for Bottles and Cages haveing sales more than 150$
My initial query
select
([Product].[Subcategory].[Subcategory],[Measures].[Internet Sales Amount]
)
on columns,
[Customer].[City].[City]
on rows
from
[Adventure Works]
Result
Now modify the query
select
([Product].[Subcategory].[Subcategory],[Measures].[Internet Sales Amount]
)
on columns,
filter
(
[Customer].[City].[City], [Measures].[Internet Sales Amount]>150
)
on rows
from
(select [Product].[Subcategory].&[28] on 0 from [Adventure Works])
Result
I am trying to write a dax for the following query:
select EncounterID
,EncounterDateKey
,DxCode
,DxID
into #PatEnc
from table1
where EncounterDateKey = 20180601
and DxCode = 'Z00.00'
select count(distinct(dbf.DiagnosisCode))
from #PatEnc
left outer join tabel1 dbf on dbf.EncounterID =
#PatEnc.EncounterID
where dbf.DxCode != 'Z00.00'
My fact table has following structure
EncounterID EncounterDateKey DxCode DxID
1 20180601 Z00.00 1
1 20180601 Z00.01 2
1 20180601 D00.00 3
2 20180601 A00.0 4
2 20180601 Z00.00 1
3 20180601 B00.00 5
3 20180601 F0.0 6
so the Dax code should return the count as 3 as there are 3 different Dx Code for the Encounters that were selected when Z00.00 was selected from the slicer. I tried filter and except function for the DAX code but its not brigning the accurate results.
I get the value selected in the slicer but couldn't get the count of remaining values. Any help is appreciated.
Answer edited, after question updated:
This query returns a distinct count of non-selected DxCode(s) for Encounter ID(s) associated with the selected DxCode(s):
Count Unselected =
VAR SelectedDxCodes = VALUES ( Table1[DxCode] )
VAR SelectedEncounterIDs = VALUES ( Table1[EncounterID] )
RETURN
CALCULATE (
DISTINCTCOUNT ( Table1[DxCode] ),
ALL ( Table1[DxCode] ),
ALL ( Table1[EncounterID] ),
NOT ( Table1[DxCode] IN SelectedDxCodes ),
Table1[EncounterID] IN SelectedEncounterIDs
)
It currently returns BLANK if no DxCode slicer selection is made, as this case isn't explained in your question.
I am new to MDX queries, and working in SSAS. I have two queries that are working suitably, but I want their output combined in a single result. The two queries differ in the cities selected by their where clauses, but they both come from the same cube and use the same measure.
A_to_B: Supplier city A to Consumer city B
SELECT { [Measures].[Quantity - Transactions] } ON COLUMNS,
{ [Tb Product].[Name].[Name].ALLMEMBERS } ON ROWS
FROM [Cube]
WHERE ([Tb Supplier].[City].&[A],
[Tb Consumer].[City].&[B])
B_to_A: Supplier city B to Consumer city A
SELECT { [Measures].[Quantity - Transactions] } ON COLUMNS,
{ [Tb Product].[Name].[Name].ALLMEMBERS } ON ROWS
FROM [Cube]
WHERE ([Tb Supplier].[City].&[B],
[Tb Consumer].[City].&[A])
Is there a way for the output of these queries to be produced side-by-side by Product, like this? In SQL I would have used a FULL OUTER JOIN, but I can't figure out the equivalent in MDX.
| | A_to_B | B_to_A |
| ProductA | 10 | 2 |
| ProductB | 100 | 0 |
| ProductC | 0 | 99 |
Simply move you Where statements to columns:
Select
{[Measures].[Quantity - Transactions]} *
{
([Tb Supplier].[City].&[B], [Tb Consumer].[City].&[A]),
([Tb Supplier].[City].&[A], [Tb Consumer].[City].&[B])
} on 0,
{[Tb Product].[Name].[Name].AllMembers} on 1
From [Cube]
You may create calculated members in order to unite two tuples:
With
Member [Tb Supplier].[City].[B2A] as
Aggregate([Tb Supplier].[City].&[B], [Tb Consumer].[City].&[A])
Member [Tb Supplier].[City].[A2B] as
Aggregate([Tb Supplier].[City].&[A], [Tb Consumer].[City].&[B])
Select
{[Tb Supplier].[City].[A2B],[Tb Supplier].[City].[B2A]} on 0
From [Cube]
Where ([Measures].[Quantity - Transactions])
I tested this script and it throws an exception:
SELECT
{[Measures].[Internet Sales Amount]}
*
{
{[Geography].[Geography].[Country].&[United States] * [Product].[Category].&[1]}
,{[Geography].[Geography].[Country].&[France] * [Product].[Category].&[3]}
} ON 0
,{[Date].[Calendar].[Date].&[20070801]} ON 1
FROM [Adventure Works];
This message:
Query (5, 7) The function expects a tuple set expression for the 1
argument. A string or numeric expression was used.
This is because you need to make either side of the cross-join specifically a set - without extra brackets it does not know this and throws an exception.
So this is the "perfect" version of the script:
SELECT
{[Measures].[Internet Sales Amount]}
*
{
{[Geography].[Geography].[Country].&[United States]} * {[Product].[Category].&[1]}
,{[Geography].[Geography].[Country].&[France]} * {[Product].[Category].&[3]}
} ON 0
,{[Date].[Calendar].[Date].&[20070801]} ON 1
FROM [Adventure Works];
I'd prefer to move the measure to the WHERE clause and also get rid of some of the redundant braces:
SELECT
{
{[Geography].[Geography].[Country].&[United States]}
*
{[Product].[Category].&[1]}
,
{[Geography].[Geography].[Country].&[France]}
*
{[Product].[Category].&[3]}
} ON 0
,[Date].[Calendar].[Date].&[20070801] ON 1
FROM [Adventure Works]
WHERE
[Measures].[Internet Sales Amount];
Translated to your cube:
SELECT
{
{[Tb Supplier].[City].&[B]} * {[Tb Consumer].[City].&[A]}
,
{[Tb Supplier].[City].&[A]} * {[Tb Consumer].[City].&[B]}
} ON 0
,[Tb Product].[Name].[Name].ALLMEMBERS ON 1
FROM [Cube]
WHERE
[Measures].[Quantity - Transactions];
Building on the others, here is one that replaces nulls with zeros in the output.
With
Member [Tb Supplier].[City].[B2A] as
Aggregate([Tb Supplier].[City].&[B], [Tb Consumer].[City].&[A])
Member [Tb Supplier].[City].[A2B] as
Aggregate([Tb Supplier].[City].&[A], [Tb Consumer].[City].&[B])
Member [Measures].[Quantity_Transactions] as
Iif( IsEmpty( [Measures].[Quantity - Transactions] ),
0,
[Measures].[Quantity - Transactions] )
SELECT
{ [Measures].[Quantity_Transactions] } *
{ [Tb Supplier].[City].[B2A],
[Tb Supplier].[City].[A2B] } on COLUMNS
, [Tb Product].[Name].[Name].ALLMEMBERS ON ROWS
FROM [Cube]
I have a query that does a distinct count of accounts based on CB score. The problem I have is that an account can switch credit scores pretty often. So I would like to take the max credit score for a particular account.
Here is what I have that is returning higher than I want because of the switching of CB scores.
So for example account 1234 initially has a cb score of 500, then later has a cb score of 550. The account 1234 is now in both cb score ranges, but I only want to count them once.
WITH
MEMBER mem1 AS
Count
(
NonEmpty
(
[AccountID].[Account ID].[Account ID].MEMBERS
,measures.[Transaction Amount]
)
)
SELECT
NON EMPTY
{mem1} ON 0
,[CB Score].[RANGE].[RANGE] ON 1
FROM [CUBE]
WHERE [PROMO].[PROMO].&24
Try this:
WITH
MEMBER mem1 AS
Sum
(
[AccountID].[Account ID].[Account ID].MEMBERS
,IIF(
Not IsEmpty([Measures].[Transaction Amount])
And IsEmpty(Sum({[CB Score].[RANGE].CurrentMember.NextMember : null}, [Measures].[Transaction Amount])),
1,
Null
)
)
SELECT
NON EMPTY
{mem1} ON 0
,[CB Score].[RANGE].[RANGE] ON 1
FROM [CUBE]
WHERE [PROMO].[PROMO].&24
Basically the logic is to count the account if they had a transaction in that slice and if no greater CB Score range has a transaction.
I'm using a MDX query to get the top 10 liked Products between two dates. Oddly, the result is composed by some Products with likes within that date range, and some without any likes at all. Here is the query:
SELECT
{ [Measures].[Likes] } ON COLUMNS,
{ TOPCOUNT([Products].[Name].Members, 10, [Measures].[Likes]) } ON ROWS
FROM [Likes]
WHERE ( [Date].[2014].[3].[29]:[Date].[2014].[4].[5] )
Here are the results:
[Measures].[Likes]
[Product].[XX]
[Product].[XX]
[Product].[XX] 139
[Product].[XX]
[Product].[XX] 1
[Product].[XX]
[Product].[XX]
[Product].[XX] 125
[Product].[XX] 111
[Product].[XX] 1
If I change the top limit to 20, for example, the results will have more products with likes but also with more empty ones, and not ordered (like a top usually is).
Using NON EMPTY makes the query return only 5 results instead of 10, and still not ordered.
Thanks!
Try this query
SELECT
{ [Measures].[Likes] } ON 0,
Head(ORDER([Products].[Name].Members,[Measures].[Likes], DESC), 10) ON 1
FROM [Likes]
WHERE ( [Date].[2014].[3].[29]:[Date].[2014].[4].[5] )