MDX Calculated member with filter - ssas

Being pretty new to MDX so this might be a rookie question. But have not been able to "translate" any answers to a solution!
I have a Measure which Counts my number of rows called [Measures].[Fact Count]
I also have a Dimension called [Document] which has a field called [Is Completed].
The [Document].[Is Completed] can have one of two values: [Yes] or [No].
The [Document] dimension does have several other fields, like [Document Type]
What I would like to ask a question like "How big a percentage of my different document types have been completed".
I have tried making a [Completed Count] like this:
([Measures].[Fact Count],
[Document].[Is Completed].&[Yes])
and then use it like:
[Measures].[Completed Count]/[Measures].[Fact Count]*100
But (of course) the [Completed Count] then takes all my completed documents instead of only those per e.g. [Document Type]
Hope this makes sense to someone!

Ah, got the solution!
Since my Dimension contains "Yes" or "No" values, I can convert them to 1 and 0 and add them to my [Measures] as [Measures].[Is Completed Sum]. And as the name says: I'll sum the values.
Then the calculation is straight forward:
[Measures].[Is Completed Sum]/
[Measures].[Fact Count]*100
or if I will make sure not to divide by 0:
iif(
[Measures].[Fact Count] = 0,
null,
[Measures].[Is Completed Sum]/
[Measures].[Fact Count]*100
)
I will still keep my Yes/no's in the Dimension as well since I can use them as filters when needed.
whytheq, thank you very much for all your input! It was very valuable and made my brain spin in the right direction :-)

Maybe it is the other side that needs to be more explicit?
(
([Measures].[Fact Count],
[Document].[Is Completed].&[Yes])
/
([Measures].[Fact Count],
[Document].[Is Completed].[All])
)
*100
If you have an attribute hierarchy for Is Completed try using that - probably like this...
(
([Measures].[Fact Count],
[Is Completed].[Is Completed].[Is Completed].&[Yes])
/
([Measures].[Fact Count],
[Is Completed].[Is Completed].[All])
)
*100
or this
(
([Measures].[Fact Count],
[Is Completed].[Is Completed].&[Yes])
/
([Measures].[Fact Count],
[Is Completed].[All])
)
*100
If you change the measure to the following and put Yes | No ON COLUMNS do you start to get the correct results?
(
([Measures].[Fact Count])
/
([Measures].[Fact Count],
[Document].[Is Completed].[All])
)
*100

Maybe SCOPE it.
(stole the code from whytheq, i think hes got the right answer)
SCOPE ([Document].[Is Completed].&[Yes])
THIS = (
([Measures].[Fact Count],
[Document].[Is Completed].&[Yes])
/
([Measures].[Fact Count],
[Document].[Is Completed].[All])
)
*100
END SCOPE
Regarding
Since my Dimension contains "Yes" or "No" values, I can convert them to 1 and 0
You could improve your model and add a new Column Value to your Dimension.
And actually get the 1 and 0 with just < Member>.VALUE

Related

Error in SQL Server CTE statement

I believe I'm writing this CTE wrong, I'm a major novice with this so explain as much as you can. Still getting the can not be bound error on almost everything
Error messages:
The multi part identifier could not be bound "PS_Margin.Emp or Vendor ID
The multi part identifier could not be bound "PS_Margin.Project Profit by Person %
Issues/ Goals:
Possible need to add aliases to column names with spaces and special characters although I don't know how to do this
WITH
Profit_Score_CTE ( [Emp or Vendor ID], [Project Profit by Person %] ) AS (
SELECT PS_Margin.[Emp or Vendor ID],
CASE
WHEN ps.[Project Profit by Person %] > .4 THEN 1
WHEN ps.[Project Profit by Person %] > .2 THEN 3
WHEN ps.[Project Profit by Person %] > .1 THEN 5
WHEN ps.[Project Profit by Person %] > .05 THEN 8
ELSE 13 END
AS [Profit Score]
FROM dbo.PS_Margin AS ps
)
SELECT emp.[Employee Name], emp.[USID], [Profit Score]*0.3 AS [Final Score]
FROM dbo.PS_Emp AS emp
left join Profit_Score_CTE
ON emp.USID = Profit_Score_CTE.[Emp or Vendor ID]
"Cannot be bound" usually refers to how you are ID'ing columns with a table alias. Try giving your table an alias and using that for the columns:
WITH
--Section 1: Profit Score
Profit_Score_CTE( [Emp or Vendor ID], [Project Profit by Person %] ) AS (
SELECT PS_Margin.[Emp or Vendor ID],
CASE
WHEN ps.[Project Profit by Person %] > .4 THEN 1
WHEN ps.[Project Profit by Person %] > .2 THEN 3
WHEN ps.[Project Profit by Person %] > .1 THEN 5
WHEN ps.[Project Profit by Person %] > .05 THEN 8
ELSE 13 END
AS [Profit Score]
FROM [dbo].[PS_Margin] ps
)
I'm guessing because you haven't provided enough information to reproduce the error. But I think the problem might be that you define the columns of your CTE here:
Profit_Score_CTE( [Emp or Vendor ID], [Project Profit by Person %] ) AS (
And yet you alias your second column with a different name here:
AS [Profit Score]
You need to decide which column name you want your CTE to expose and use it consistently.
I'll assume your CTE is correctly defined. Your cte is named "Profit_Score_CTE". Your actual select statement refers to objects dbo.PS_Emp and dbo.PS. I'll guess that you should replace dbo.PS with your CTE name. E.g.,
with Profit_Score_CTE as (select ...)
select emp.[Employee Name], ...
from dbo.PS_Emp as emp
left join Profit_Score_CTE
on emp.USID = Profit_Score_CTE.[Emp or Vendor ID]
order by ...
;
The alias PS is visible only inside the definition of the CTE. It cannot be used in the actual select statement that uses your CTE. Notice that I gave your table an alias and used it - a consistent coding style is something you should strive to achieve. Also notice the order by clause. Rows within a resultset have no defined order without one - and usually it is important. And PLEASE use white space to make your code readable and to avoid easy mistakes. You crammed everything together in the formula for computed column [Final Score].
Thanks all for your help!
My newbie ribbon was really showing with this one. The problem had nothing to do with SQL at all. I wasn't pointing to the correct database in sql server.
In the available databases drop down box on the top left hand screen of SQL Server you need to select the database you're working from. This will enable the script to find your database, and begin to solve alot of the errors.

How to filter on mdx dimension

I have a query which i want to filter it on max of one of its dimension fields like this:
SELECT
{
[Measures].[F Sra Quantity],
[Measures].[F Sra Gross],
[Measures].[F Sra Disc TOTAL]
}
DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME
ON COLUMNS,
NON EMPTY
CrossJoin(
{[Branch Dim].[b Name].Children},
{[Date Dim].[d Year Month].Children},
{[Date Dim].[Full Date].Children},
{[Customer Dim].[c Name].Children},
{[Customer Dim].[c Path].Children},
{[Order Specification Dim].[Os Type No].Children},
{[Sales Team Dim].[Id].Children},
{[Sales Team Dim].[St Visitor].Children}
)
ON ROWS
FROM [D Sys Warehouse]
I want to filter it on the max value of [Os Type No] which its members are changing always. would you help me please?
Not tested as I'm not near SSAS or the AdvWrks cube but something along these lines might work, assuming I have interpreted your request correctly:
WITH MEMBER [Measures].[MAX_No] AS
MAX(
[Order Specification Dim].[Os Type No].MEMBERS,
[Order Specification Dim].[Os Type No].CURRENTMEMBER.MEMBER_VALUE
)
SELECT
{
[Measures].[F Sra Quantity],
[Measures].[F Sra Gross],
[Measures].[F Sra Disc TOTAL]
}
DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME
ON COLUMNS,
NON EMPTY
CrossJoin(
{[Branch Dim].[b Name].Children},
{[Date Dim].[d Year Month].Children},
{[Date Dim].[Full Date].Children},
{[Customer Dim].[c Name].Children},
{[Customer Dim].[c Path].Children},
{[Order Specification Dim].[Os Type No].Children},
{[Sales Team Dim].[Id].Children},
{[Sales Team Dim].[St Visitor].Children}
)
HAVING
[Order Specification Dim].[Os Type No].CURRENTMEMBER.MEMBER_VALUE = [Measures].[MAX_No]
ON ROWS
FROM [D Sys Warehouse]

MDX Query to Filter by Date Dimensions

I am new to MDX queries and am trying to figure out how to filter a result set using date dimensions.
Let's take a cube structured like this (contrived example):
I would like to give the user a list of projects to select, and display the cost of all events that occurred during the selected projects (i.e. between start date and end date). However, the events are not linked to projects.
Using the query:
SELECT NON EMPTY
{
[Measures].[Cost]
}
ON COLUMNS,
NON EMPTY
{
(
[Project Details].[Project].[Project].ALLMEMBERS
* [Project Details].[Start Date].[Start Date].ALLMEMBERS
* [Project Details].[End Date].[End Date].ALLMEMBERS
* [Event Details].[Date of Occurrence].[Date of Occurrence].ALLMEMBERS
)
}
DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME
ON ROWS
FROM [Cube]
CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS
I can get a list of items like this:
Project Start Date End Date Date of Occurrence Cost
------------------------------------------------------------------
Project 1 01-Jan-15 31-Jan-15 27-Dec-14 750
Project 1 01-Jan-15 31-Jan-15 01-Jan-15 680
Project 1 01-Jan-15 31-Jan-15 02-Jan-15 320
Project 1 01-Jan-15 31-Jan-15 03-Jan-15 150
Project 1 01-Jan-15 31-Jan-15 01-Feb-15 700
Project 1 01-Jan-15 31-Jan-15 05-Feb-15 175
If I run the query for Project 1 only, it should exclude the first event and last 2 events.
Would the best approach be to use a WHERE or FILTER? And because these are dimensions and not measures, how would I do a comparison of WHERE [Date of Occurrence] BETWEEN [Start Date] AND [End Date]?
Any help is much appreciated.
I would try something like this:
WITH MEMBER [Measures].[Cost in period] AS
IIF(
[Event Details].[Date of Occurrence].CurrentMember.Properties('Key') >=
[Project Details].[Start Date].CurrentMember.Properties('Key') &&
[Event Details].[Date of Occurrence].CurrentMember.Properties('Key') <=
[Project Details].[End Date].CurrentMember.Properties('Key'),
[Measures].[Cost], NULL)
SELECT NON EMPTY
{
[Measures].[Cost in period]
}
ON COLUMNS,
NON EMPTY
{
(
[Project Details].[Project].[Project].ALLMEMBERS
* [Project Details].[Start Date].[Start Date].ALLMEMBERS
* [Project Details].[End Date].[End Date].ALLMEMBERS
* [Event Details].[Date of Occurrence].[Date of Occurrence].ALLMEMBERS
)
}
ON ROWS
FROM [Cube]
Basically, you create a calculated measure which is NULL when the Date of Occurrence lies outsite the Start Date - End Date interval. Thanks to NON EMPTY on the Row members, the data should be filtered out of the result.
If [Event Details] and [Project Details] are role playing dimensions, you can put the LINKMEMBER MDX function to use to help you. Also, I am assuming you would be using some sort of front end(maybeSSRS) to give the user the freedom to choose the start and end dates(as parameters or calendar control). In that case, they will enter the MDX query as strings. STRTOMEMBER function converts those string to members.
Using LINKMEMBER, once I generate a set of dates, I am using AGGREGATE function to get the aggregated value of measure for this set of dates.
with set [Start Date] as
linkmember(STRTOMEMBER('[Project Details].[Start Date].[Start Date].&[01/01/2014]'), [Event Details].[Date of Occurrence])
set [End Date] as
linkmember(STRTOMEMBER('[Project Details].[End Date].[End Date].&[01/01/2015]'), [Event Details].[Date of Occurrence])
set ListOfDate as
{[Start Date].item(0):[End Date].item(0)}
member [Measure.NetCost] as
aggregate(ListOfDates, [Measures].[Cost])
SELECT NON EMPTY
{
[Measure.NetCost]
}
ON COLUMNS,
NON EMPTY [Project Details].[Project].[Project].ALLMEMBERS
DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME
ON ROWS
FROM [Cube]
CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS
DISCLAIMER: As stated, it would work only if the [Event Details] and [Project Details] are role playing dimensions.
I am not sure if this code would work in your scenario, but I have found this function quite handy at times. To read more on LINKMEMBER function, see here.
Not tested. I've not used && before - maybe just the keyword AND would suffice:
SELECT NON EMPTY
{
[Measures].[Cost]
}
ON COLUMNS,
NON EMPTY
{
(
[Project Details].[Project].[Project].ALLMEMBERS
* [Project Details].[Start Date].[Start Date].ALLMEMBERS
* [Project Details].[End Date].[End Date].ALLMEMBERS
* [Event Details].[Date of Occurrence].[Date of Occurrence].ALLMEMBERS
)
}
HAVING [Event Details].[Date of Occurrence].CurrentMember.MEMBERVALUE >=
[Project Details].[Start Date].CurrentMember.MEMBERVALUE
&& //<< OR IS THIS JUST "AND"?
[Event Details].[Date of Occurrence].CurrentMember.MEMBERVALUE <=
[Project Details].[End Date].CurrentMember.MEMBERVALUE
ON ROWS
FROM [Cube]

calculate percentage of individual categories in MDX

I want to calculate percentage of individual Categories, Here is my mdx code.
WITH
MEMBER [Measures].[Individual_Total] AS ([DIM RATING STRINGS].[LABEL]*[Measures].AGG_RATING Count])
SELECT
NONEMPTY {
[Measures].[AGG_RATING Count],[Measures].[Individual_Total]
} ONColumns,
([DIM STRUCTURE].[PARENT CODE].&[M01]&[M]:[DIM STRUCTURE].[PARENT CODE].&[M11]&[M],
[DIM TAILORING].[TAILORING_LABEL].[TAILORING_LABEL],
{[DIM RATING STRINGS].[LABEL].[LABEL],[DIM RATING STRINGS].[LABEL]}
) onrows
FROM [Cube]
Here is the output
In this output we have 4 categories like ""External Drivers ,stretegy,Business operation and governance.
I need to calculate percentage of different color with in the same category.
For example if we take "External Drivers" then Calculation should be like
amber = 15/28 * 100, green = 5/28/*100 etc because 28 is the sum of external drivers.
Please tell me how to do this thing in mdx.
thanks
Here you can compare with my solution, it will give you the percent of the parent.
with
member [Measures].[Percent of parent] as
([Measures].[Order Quantity]) /
([Product].[Product Categories].currentmember.parent,
[Measures].[Order Quantity])
,format_string = "percent"
SELECT
{([Measures].[Order Quantity]),
([Measures].[Percent of parent])} ON COLUMNS,
{[Product].[Product Categories].[Category].&[3]} *
{[Product].[Subcategory].[Subcategory].Members} *
{[Product].[Style].[Style].Members} *
{[Product].[Product].members}
ON ROWS
FROM [Cube]
I donĀ“t know if i read your dimensions correctly but maybe your member should look something like:
with member [Measures].[Percent] as
[Measures].[AGG_RATING Count] /
([DIM RATING STRINGS].[LABEL].CURRENTMEMBER.PARENT,
[Measures].[AGG_RATING Count])
, format_string = "percent"

MDX Query Problem

Im new to MDX . I am trying to perform the following result.
Attended Client Count Client Count
--------------------- -----------------
723 1223
And I tried to do this :
WITH MEMBER [Attended Client] AS
[Measures].[Client Count]
SET [Attended Client Set] AS
FILTER
(
[Dim Client Attendance].[Attended].&[Attended],
[Measures].[Client Count] <>0
)
SELECT {[Measures].[Client Count],[Attended Client] } ON COLUMNS
FROM [Client Intervention]
And it throws me an error : Two sets specified in the function have different dimensionality. I'm able to do [Measures].[Client Count] OR [Attended Client] at a time, but not together. Any solution for this??? Thanks
Here is a link about a gentle introduction to MDX where you can have a look for tuples/sets. The following query should do what you want:
WITH MEMBER [Measures].[Attended Client Client] AS
Aggregate( FILTER (
[Dim Client Attendance].[Attended].&[Attended],
[Measures].[Client)Count] <>0
),
[Measures].[Client Count]
)
SELECT {[Measures].[Attended Client Client],[Measures].[Client Count] } ON COLUMNS
FROM [Client Intervention]