Mdx - Flag -Actual - mdx

I have two dimensions DimFlag and DimPNL and a fact table FactAmount. I am looking to:
When pnl is stat(Is Stat=1) : sum (Actual x FlagId)
For pnl I multiply the amounts by field FlagId basically if it will be so 0 0 X = 0 ...
DimFlag
FlagId FlagLabel
-----------------
1 NotClosed
0 IsClosed
DimPNL
PNLId PNLName Is Stat
1 a 1
2 test 1
3 test2 0
FactAmount
id PNLId FlagId Actual
1 1 1 100
2 2 1 10
3 3 0 120
I tried the following MDX but it didn't work, any idea please ?
Scope (
[Dim PNL].[PNL].members,[Measures].members
);
this = iif([Dim PNL].[PNL].CurrentMember.Properties("Is Stat") =1
,
aggregate([Dim PNL].[PNL].currentmember,[Measures].currentmember)* iif([Dim Flag].[Flag Label].[Flag Label].currentmember = 0, 0, 1),
aggregate([Dim PNL].[PNL].currentmember,[Measures].currentmember)
);

While this type of calculation can be done in MDX, the MDX can get complex and performs bad. I would suggest to explicitly do the calculation e. g. in the DSV or a view on the fact table that you then use instead of the fact table directly in the DSV. The result of the calculation would then be another column on which you can base a standard measure.
To do it in the DSV, assuming you use a relational table as the base for the fact table, add a named calculation to it, define the column name however you like, and use the expression Actual * FlagID. For the other calculation, you may need a subselect, i. e. the expression would be Actual * case when pnlId in(1,2) then 1 else 0 end. You can use any SQL that works as a column expression in the select list as the expression in for a named calculation.
Implementing the same in a view on FactAmount, you could implement the second expression better, as then you could join table DimPNL in the view definition and thus use column IsStat in the calculation. Then you would replace table FactAmout by the view, which has the two additional measure columns.
In either case, just define two measures on the two new columns in the cube, and you are done.
As a rule, calculations that are done on record level in the fact table before any aggregation should be done at data loading time, i. e. as described above.

Related

How to multiply two measures prior to aggregation

I have two measures. The first is amount, and the second consist of values -1,0 and 1, so table looks like this:
Amount Sign
--------------
400 -1
200 1
300 0
Result I want to get is 400*(-1) + 200*1 + 300*0 = -200, but I am getting (400+200+300)*(-1+1+0) = 0
This is my calculated member:
WITH
MEMBER [Measures].[Result]
AS
[Measures].[Sign]*[Measures].[Amount]
select
[Measures].[Result] on 0,
[Time].[Time].members on 1
from [MyCube]
In you SSAS project, go to the datasource view, for the underlying fact table add a NamedCalculation. In that do the multiplication that you explained. Now in the Cube add that as a measure. It will behave exactly like you want it to behave.

Oracle SQL - Multiple return from case

I may be trying it wrong. I am looking for any approach which is best.
Requirement:
My Query joins 4-5 tables based on few fields.
I have a column called product id. In my table there are 1.5 million rows. Out of those only 10% rows has product ids with the following attribute
A300X-%
A500Y-%
300,500, 700 are valid model numbers. X and Y are classifications. My query picks all the systems.
I have a check as follows
CASE
WHEN PID LIKE 'A300X%'
THEN 'A300'
...
END AS MODEL
Similarly
CASE
WHEN PID LIKE 'A300X%'
THEN 'X'
...
END AS GENRE
I am looking for the best option from the below
How do I Combine both case statement and add another[third] case which will have these two cases. i.e
CASE
WHEN desc in ('AAA')
First Case
Second Case
ELSE
don't do anything for other systems
END
Is there any regex way of doing this? Before first - take the string. Look for X, Y and also 300,500,700.
Is there any other way of doing this? Or doing via code is the best way?
Any suggestions?
EDIT:
Sample desc:
AAA,
SoftwARE,
sw-app
My query picks all the desc. But the case should be running for AAA alone.
And Valid models are
A300X-2x-P
A500Y-5x-p
A700X-2x-p
A50CE-2x-P
I have to consider only 300,500,700. And the above two cases.
Expected result:
MODEL GENRE
A300 X
A500 Y
A300 Y
Q: How do I Combine both CASE statement expressions
Each CASE expression will return a single value. If the requirement is to return two separate columns in the resultset, that will require two separate expressions in the SELECT list.
For example:
DESC PID model_number genre
---- ---------- ------------ ------
AAA A300X-2x-P 300 X
AAA A500Y-5x-p 500 Y
AAA A700X-2x-p 700 X
AAA A50CE-2x-P (NULL) (NULL)
FOO A300X-2x-P (NULL) (NULL)
There will need to be an expression to return the model_number column, and a separate expression to return the genre column.
It's not possible for a single expression to return two separate columns.
Q: and add another[third] case which will have these two cases.
A CASE expression returns a value; we can use a CASE expression almost anywhere in a SQL statement where we can use a value, including within another CASE expression.
We can also combine multiple conditions in a WHEN test with AND and OR
As an example of combining conditions and nesting CASE expressions ditions...
CASE
WHEN ( ( t.PID LIKE '_300%' OR t.PID LIKE '_500%' OR t.PID LIKE '_700%' )
AND ( t.DESC = 'AAA' )
)
THEN CASE
WHEN ( t.PID LIKE '____X%' )
THEN 'X'
WHEN ( t.PID LIKE '____Y%' )
THEN 'Y'
ELSE NULL
END
ELSE NULL
END AS `genre`
There are other expressions that will return an equivalent result; the example shown here isn't necessarily the best expression. It just serves as a demonstration of combining conditions and nesting CASE expressions.
Note that to return another column model we would need to include another expression in the SELECT list. Similar conditions will need to be repeated; it's not possible to reference the WHEN conditions in another CASE expression.
Based on your sample data, logic such as this would work:
(CASE WHEN REGEXP_LIKE(PID, '^A[0-9]{3}[A-Z]-')
THEN SUBSTR(PID, 1, 4)
ELSE PID
END) AS MODEL
(CASE WHEN REGEXP_LIKE(PID, '^A[0-9]{3}[A-Z]-')
THEN SUBSTR(PID, 5, 1)
ELSE PID
END) AS GENRE
This assumes that the "model number" always starts with "A" and is followed by three digits (as in your example data). If the model number is more complicated, you may need regexp_substr() to extract the values you want.

SSAS Cube - Excel Drill through not filtered as required

I have a SSAS DSV similar to following structure:
Id Type Special
1 A 1
2 B Null
3 A Null
4 C 1
5 C Null
I built a dimension for this DSV including one attribute for Type.
Then I have in my cube three measures
Measure1: Count of rows
Measure2A: Sum of Special
Measure2B: Count of non-empty values for Special
Finally in Excel, I display data as following:
Rows --> Type attribute
Values --> Measure1 / Measure2A / Measure2B
When I look at the results, everything is correct.
For instance, I get a count of 1 for measure2A and measure 2B for row = C
BUT when I attempt to drill through for related cells, instead of getting 1 row, I get 2 (the ones where type = C without considering the value of Special)
I guess I am doing something wrong in my design of the cube but cannot understand what.
When determining what rows to show in drillthrough SSAS only considers the dimension context not which detail rows have a non null measure value.
You could add a new dimension on the Special column and add that dimension as a filter to your PivotTable.
Or you could install ASSP and construct a custom rowset action that fires an MDX query which does a NON EMPTY on your measure.
http://asstoredprocedures.codeplex.com/wikipage?title=Drillthrough&referringTitle=Home

How to filter measures in MDX

I need to filter the measure values as
MeasureA MeasureB
10 10
15 15
5 20
20 20
Here I need to get only the measures are not equal, I am using filter function as but not working
Select Filter({[Measures].[A],
[Measures].[B]},
([Measures].[A]-
[Measures].[B])=0)
on 0
from [Cube]
Expected result set
MeasureA MeasureB
5 20
What am I missing?
Try using a dimension instead of your measures for the first part of the filter statement. Assuming you are querying products then your query might look like:
select {[Measures].[A],[Measures].[B]} on columns,
filter ({[Products].Members},[Measures].[A] = [Measures].[B]) on rows
from [Sales Cube]
You might want to try creating a calculated field in the DSV for this Fact table...
CASE
WHEN MeasureFieldA != MeasureFieldB THEN 1
ELSE 0
END
Then you can create a "fact dimension" and have this calculated field as an attribute to be used in your queries or calculated measures.

MDX for calculating measure given equality of 2 member attributes from 2 different dimensions

I have the following structure of measures and dimensions, and some example data
Fact Table:
id_dim1 id_dim2 id_dim ...measure1
1 2 ...120
2 1 ...101
1 1 ...95
3 3 ...12
Dim1:
id_dim1 member1value
1 Value1
2 Value2
3 Value3
Dim2:
id_dim2 member2value
1 Value1
2 Value2
3 Value3
Dim1 and Dim2 are actually roleplaying dimension and are based on the same dimension table
I want to calculate a measure which sums measure1 only when:
[Dim1].[Hierarchy1].[Level based on member2value]=[Dim2].[Hierarchy1].[Level based on member2value]
In the above example, the measure would be calculated as: 95+12=107
The catch is that I want the measure calculated correctly even though Dim1 and Dim2 are not used in the later mdx query.
So far I have the following, which only works when Dim1 and Dim2 are used in the later query:
Member [Measures].[CondMeasure] AS 'IIF(
[Dim1].[Hierarcy1].[All].[Level].CurrentMember.Name =
[Dim2].[Hierarchy1].[All].[Level].CurrentMember.Name
,
([Measures].[Measure1],
[DimXX].[Hxx].[LevelXX].[MemberXX],
[DimYY].[Hyy].[LevelYY].[MemberYY])
),
0
)
'
The measure is also only calculated in context of some other members, as demonstrated above.
Btw. I am trying this in SSAS
Regards
Soeren
What do you think about creation additional field in fact table or expression in DSV?
case
when id_dim1 = id_dim2 then measure1
else 0
end
after that you can create new metric...
In some situations it's easier than writing difficult mdx-expressions.