I have following Dimensions of same level :
[Area].[Area ID]
[Discipline].[Discipline ID]
and i have following measure:
[Measures].[Risk Score]
Note: These dimensions are related to the fact through a Many-to-many relations through another fact table (Project)
I want to retrieve the Top 5 Risks for every discipline in every Area so for example,
If we have Discipline: Mechanical; and Area: A & B
I want to get:
1) Top 5 Risks of Mechanical Discipline in Area A
2) Top 5 Risks of Mechanical Discipline in Area B
I tried the following code which for some reason is only working for the First Area :
Exists
(
[Risk Dimensions].[RISKSID].[RISKSID],
GENERATE
(
EXCEPT([Area].[Area ID].MEMBERS, [Area].[Area ID].UNKNOWNMEMBER),
[Area].[Area ID].CURRENTMEMBER
*
GENERATE
(
EXCEPT([Discipline].[Discipline ID].MEMBERS, [Discipline].[Discipline ID].UNKNOWNMEMBER),
[Discipline].[Discipline ID].CURRENTMEMBER
*
TopCount
(
[Risk Dimensions].[RISKSID].[RISKSID],
5,
[Measures].[Assessment P-I Score Float]
)
)
)
)
For some reason it is only working for the First Area and the next one will have extra fields
Any help is appreciated
Related
I need to merge the result 2 queries into one table. Queries are similar except one of WHERE conditions.
As far as I was able to find out while googling it is impossible to do as MDX have internal connections in database design.
I have tried to use this way: Merge 2 MDX queries
But it turns out that in 1 hour I get this error:
XML for Analysis parser: The XML for Analysis request timed out before it was completed.
I have tried to make new members like that:
member new_A AS
aggregate
(
K
,
A
)
And then
select { new_A, ...
select { A , B , C , D } on 0,
non empty { Y * Z } on 1
from X
where (except(K), L, M, N, P);
select { A , B , C , D } on 0,
non empty { Y * Z } on 1
from X
where (K, L, M, N, P);
What I need to get in the end is a table that contains values of elements A,B,C,D as columns for condition K only and for all except condition K just next to it. it can be either A, new_A, B, new_B, etc or A, B, C, D , new_A, new_B, etc.
P.S. database is extremely big and the faster it works the better :)
So i have tried to map your problem to AdventureWorks sample database.
In my problem i am trying report [internet Sales Amount] for some countries for a set of subcategories. Then I edit my query to report all subcategories except "Road Bikes" in main columns and for road bikes i use measures.RoadBikes.
Query 1
with member
measures.RoadBikes
as
( ([Product].[Subcategory].&[2],[Measures].[Internet Sales Amount]))
select
non empty
{
({[Customer].[Country].&[Australia],[Customer].[Country].&[Canada],[Customer].[Country].&[France],[Customer].[Country].&[United Kingdom],[Customer].[Country].&[United States]},
[Measures].[Internet Sales Amount]
),
({[Customer].[Country].&[Australia],[Customer].[Country].&[Canada],[Customer].[Country].&[France],[Customer].[Country].&[United Kingdom],[Customer].[Country].&[United States]},
measures.RoadBikes
)
}
on columns,
non empty
[Date].[Month of Year].[Month of Year]
on
rows
from
[Adventure Works]
where
({[Product].[Subcategory].&[31],[Product].[Subcategory].&[1],[Product].[Subcategory].&[2],[Product].[Subcategory].&[37],[Product].[Subcategory].&[3]})
Result
Edit the query
with member measures.UsRoadBikes as ([Product].[Subcategory].&[2],[Measures].[Internet Sales Amount])
select non empty
{({[Customer].[Country].&[Australia],[Customer].[Country].&[Canada],[Customer].[Country].&[France],[Customer].[Country].&[United Kingdom],[Customer].[Country].&[United States]},
[Measures].[Internet Sales Amount])}
on columns,
non empty
({[Product].[Subcategory].&[31],[Product].[Subcategory].&[1],[Product].[Subcategory].&[2],[Product].[Subcategory].&[37],[Product].[Subcategory].&[3]},
[Date].[Month of Year].[Month of Year]
) on rows
from [Adventure Works]
Result
Thanks everyone!
It was decided to run queries in parallel to speed up.
Return data to be populated into dataset and then Linq to be used to work with it.
I have a MDX query below. This query works, the problem is it is slow, takes > 15 secs to return results even though the data set is not huge. I believe the query should execute under 2 secs (its also used on a landing page and the wait time is bothersome). The [Measures].[Star Rating] is causing the slow down because of all the IF THEN ELSE logic. All its doing is based on the [Mean Score], it finds the [Star Rating] from a lookup table based on the range in the lookup table.
For e.g. if [Mean Score] < 86, [Star Rating] = 1
if [Mean Score] >= 86 and <= 90, [Star Rating] = 2
The [Mean Score] is a simple sum/count calculation.
It can change based on the date range being used as parameter.
Can you recommend either an optimization in the existing query below or recommend an alternate way to calculate [Star Rating] ?
The MDX query is below:
WITH
MEMBER [Measures].[MeanScore] AS ([Measures].[Standard Point Assignment - Sum]/[Measures].[Episode Of Care HCAHPS Count])
MEMBER [Measures].[StarRating] AS
CASE
WHEN [HCAHPS Star Rating].[HCAHPS Star Rating ID].CurrentMember IS [HCAHPS Star Rating].[HCAHPS Star Rating ID].[All]
THEN
CASE
WHEN [Measures].[HSR-HCHCAHPS Domain ID] = TAIL([HCAHPS Star Rating].[HCAHPS Star Rating ID].[HCAHPS Star Rating ID]).Item(0).Item(0).Properties('HCHCAHPS Domain ID')
THEN
(
[Measures].[Rating],
Tail([HCAHPS Star Rating].[HCAHPS Star Rating ID].[HCAHPS Star Rating ID]).Item(0).Item(0)
)
ELSE
(
[Measures].[StarRating],
Tail([HCAHPS Star Rating].[HCAHPS Star Rating ID].[HCAHPS Star Rating ID]).Item(0).Item(0).PrevMember
)
END
ELSE
CASE
WHEN [Measures].[MeanScore] > [HCAHPS Star Rating].[HCAHPS Star Rating ID].CurrentMember.Properties('Start', typed)
AND [Measures].[HC-HCAHPS Domain ID] = [HCAHPS Star Rating].[HCAHPS Star Rating ID].CurrentMember.Properties('HCHCAHPS Domain ID', typed)
THEN
(
[Measures].[Rating],
[HCAHPS Star Rating].[HCAHPS Star Rating ID].CurrentMember
)
ELSE
(
[Measures].[StarRating],
[HCAHPS Star Rating].[HCAHPS Star Rating ID].CurrentMember.PrevMember
)
END
END
SELECT
{
[Measures].[Episode Of Care HCAHPS Count]
,[Measures].[Is Top Box]
,[Measures].[CompositeScore]
,[Measures].[PromoterCount]
,[Measures].[PromoterPercent]
,[Measures].[PassiveCount]
,[Measures].[PassivePercent]
,[Measures].[DetractorCount]
,[Measures].[DetractorPercent]
,[Measures].[StarRating]
,[Measures].[MeanScore]
} ON COLUMNS,
NONEMPTYCROSSJOIN
(
{NONEMPTY([HCAHPS Domain].[HCAHPS Survey Methodology ID].[HCAHPS Survey Methodology ID])}
,DESCENDANTS(StrToSet('[Org Hierarchy].[Parent Key].&[118418]'))
,{[HCHCAHPS Domain].[HC Domain Group].[HC Domain Group]}
,{[HCHCAHPS Domain].[HCAHPS Domain Name].[HCAHPS Domain Name]}
,{[HCAHPS Question Answer].[Question Number].AllMembers}
) ON ROWS
FROM [CAHPS]
WHERE
(
StrToMember("[Date].[Date].&[" + FORMAT(NOW()-365,"yyyy-MM-ddT00:00:00") + "]",CONSTRAINED):StrToMember("[Date].[Date].&[" + FORMAT(NOW(),"yyyy-MM-ddT00:00:00") + "]",CONSTRAINED)
)
In general, IIF and CASE statements within Analysis Services MDX could potentially see some performance degradations. While most IIF statements are relatively inexpensive, complex nested conditions (with lots of IIF statements), this would result in the Analysis Services formula engine will end up running the query cell-by-cell.
For performant queries, the goal is to have the query run in subspace mode (or block computation) instead of cell-by-cell mode. To do this within the context if IIF statements, please try to utilize SCOPE statements. A great reference to convert IIF statements to SCOPE is Mosha Pasumansky's blog post is Performance of IIF function in MDX.
By the way, for more information on subspace computation (vs. cell-by-cell), please refer to Section 3.2.1 of the Analysis Services Performance Guide
I have problem with my SSAS Cube.
I have to implement basic calculation to my Cube:
sum(Ammount) where BOOK = "Assets" and CD_PRODUCT_L4 <> "LoanLoss"
My dimmension is in image below:
Dimension attributes: BOOK, CD_PRODUCT_L4, CD_PRODUCT_L5, ..
Hierarchy PROD: CD_PRODUCT_L4 - CD_PRODUCT_L5
CREATE MEMBER CURRENTCUBE.[Measures].[Principal Loans]
AS (
except(
[PLV PRH HDIM CB].[BOOK].&[ASSETS_ON],
[PLV PRH HDIM CB].[COD PRODUCT L4].&[51L4]
),
[Measures].[EOM PRINCIPAL_a])
The biggest thing is that conditions are not from same hierarchy level so I can't use except and I know no other way to implement this particular condition set
Please HELP, Thank you
Product dimmension model
I manage to solve the issue by adding hierarchy to my dimension which allowed me to use except as I wanted before but I'am not satisfied with this solution because it looks more like workaround then solution
CREATE MEMBER CURRENTCUBE.[Measures].[Principal Loans] AS
sum((except([PLV PRH HDIM CB].[Hierarchy BOOK].[BOOK].&[ASSETS_ON].children,[PLV PRH HDIM CB].[Hierarchy BOOK].[COD PRODUCT L4].&[51L4]),[Measures].[EOM PRINCIPAL_a]))
This is probably the closest example that I can provide you to what you need.
This, code below, is just one of about 50 or so Measures we have defined, ranging from Counts, Averages, Sums, Percentages, etc. We take a single DW value and perform at least 2 seperation calculations, most have 4 or more different calculations, from that one field.
CREATE MEMBER CURRENTCUBE.[Measures].[Count Previous Difference]
AS Case
// Test for current coordinate being on (All) member.
When [Date].[YearMonth].CurrentMember.Level Is [Date].[YearMonth].[(All)]
Then "NA"
Else
( [Date].[YearMonth].CurrentMember, [Measures].[Gross Count] )
-
( ParallelPeriod (
[Date].[YearMonth].CurrentMember.Level,
1,
[Date].[YearMonth].CurrentMember
),
[Measures].[Gross Count]
)
End,
FORMAT_STRING = "#,##0.00;-#,##0.00",
NON_EMPTY_BEHAVIOR = { [Gross Count] },
VISIBLE = 0 , ASSOCIATED_MEASURE_GROUP = 'Some Summary';
Keep in mind we also use our DW & Cube with SharePoint and SSRS reports.
I would like to filter a dimension for cube security with some information that are in another dimension.
So - I have a dimension which holds some account Responsible (Account Number and the initials on the one responsible) and another Dimension with all accounts.
I would like to make sure, that a person only can see movements on the accounts on which they are responsible.
I can make the filtering work like this:
SELECT
{} ON 0
,{
Exists
(
Filter
(
[Accounts].[Accounts].[AccountNo]
*
[AccountResponsible].[AccountResponsible].[AccountNo]
,
[Accounts].[Accounts].Properties("key")
=
[AccountResponsible].[AccountResponsible].Properties("key")
)
,[AccountResponsible].[Responsible].&[MSA]
)
} ON 1
FROM mycube;
the problem is, that there are two columns, and I can't use that in cube security. Is there a way to rewrite this, so that I actually get only one column with the members that the user are allowed to see?
Try using the Extract function:
SELECT
{} ON 0
,
EXTRACT(
{
Exists
(
Filter
(
[Accounts].[Accounts].[AccountNo]
*
[AccountResponsible].[AccountResponsible].[AccountNo]
,
[Accounts].[Accounts].Properties("key")
=
[AccountResponsible].[AccountResponsible].Properties("key")
)
,[AccountResponsible].[Responsible].&[MSA]
)
}
,[Accounts].[Accounts] //<<HIERARCHY YOU WISH TO EXTRACT
) ON 1
FROM mycube;
Let's say I have two simple dimensions:
Products - with id and name
Salesmen - with id and name
My fact table is named SALES and contains the ids of the abovementioned.
I need to produce a query that will show the names of salesmen who sold all of the given products.
This code solves the problem for two items X and Y:
SELECT
{} on 0,
EXISTS(
EXISTS(
{[Salesmen].[Name].MEMBERS},
{[Products].[Name].&[X]}
)
,{[Products].[Name].&[Y]}
)
ON 1
FROM [Test];
The other version is:
SELECT
{} on 0,
INTERSECT(
NONEMPTY(
{[Salesmen].[Name].MEMBERS}
,([Products].[Name].&[X])
)
,NONEMPTY(
{[Salesmen].[Name].MEMBERS}
,([Products].[Name].&[Y])
)
)
ON 1
FROM [Test];
However, this method becomes troublesome if the list of given products is large, for example - 100 random products..
Do you have a property member_key for the hierarchy [Products].[Name] ? We can test like this:
WITH
MEMBER [Measures].[Meas1] AS
[Products].[Name].CurrentMember.PROPERTIES("KEY ID")
MEMBER [Measures].[Meas2] AS
[Products].[Name].CurrentMember.MEMBER_Key
MEMBER [Measures].[Meas3] AS
[Products].[Name].CurrentMember.MEMBERvalue
select
{
[Measures].[Meas1]
,[Measures].[Meas2]
,[Measures].[Meas3]
} on COLUMNS,
[Products].[Name].MEMBERS on ROWS
FROM [Test];
Hopefully one of the custom measures gives you a value? I'll assume Meas2 is working (swap to a different one if Meas1 or Meas3 is returning numbers)
WITH
MEMBER [Measures].[Meas2] AS
[Products].[Name].CurrentMember.MEMBER_Key
SET [ProdsetA] AS
FILTER(
[Products].[Name].MEMBERS
,[Measures].[Meas2] <100
)
SET [ProdsetB] AS
FILTER(
[Products].[Name].MEMBERS
,[Measures].[Meas2] >500
)
SELECT
{} on 0,
INTERSECT(
NONEMPTY(
{[Salesmen].[Name].MEMBERS}
,[ProdsetA]
)
,NONEMPTY(
{[Salesmen].[Name].MEMBERS}
,[ProdsetB]
)
)
ON 1
FROM [Test];
... the >100 and <500 are important. These are the criteria for the filter function to use. The custom set [ProdsetA] will only contain Products that have MEMBER_Key that are <100 whereas the custom set [ProdsetB] will only contain Products that have MEMBER_Key that are >500. You need to use the member values presented to you by the first script to decide what values 100 and 500 should be in your cube context (...I don't know the key values in your cube so just used 100 and 500 as placeholders)