MDX: RANK showing ties, even though data values are different - sql-server

The original query I had didn't have the [Row Axis] SET which appears below, it worked, but had 'duplicated' ranking values
Someone suggested that I move the row axis, but now instead of 'repeated rank values' I just get #Error showing
What is wrong with my RANK function?
WITH
SET [Row Axis] AS
/*NON EMPTY */
(
Generate
(
[PortfolioBenchmarks]
,TopCount
(
(
[Portfolio].[Portfolio Name].CurrentMember
,[Portfolio Benchmark].[Benchmark Name].CurrentMember
)
*
[Factors]
,10
,Abs([Measures].[FormattedBarraoutput])
)
)
)
SET [Portfolios] AS
{
[Portfolio].[Portfolio Name].&[thingy one]
,[Portfolio].[Portfolio Name].&[thingy two]
,[Portfolio].[Portfolio Name].&[another thingy]
,[Portfolio].[Portfolio Name].&[all these get passed in as params anyhoo]
,[Portfolio].[Portfolio Name].&[one more for luck]
}
SET [PortfolioBenchmarks] AS
{
Filter
(
[Portfolios]
*
[Portfolio Benchmark].[Benchmark Name].Children
,(NOT
IsEmpty([Measures].[Barra Relative Result Percentage]))
)
}
SET [Factors] AS
{
(
[Barra Scenario].[Barra Scenario Name].&[Eff Active Weight (%)]
,[Barra Factor].[Factor Type].&[GICSIndustry]
)
*
[Barra Factor].[Factor Value].Children
}
MEMBER [Measures].[FormattedBarraoutput] AS
IIF
(
IsEmpty([Measures].[Barra Relative Result Percentage])
,NULL
,[Measures].[Barra Relative Result Percentage]
)
MEMBER [Measures].[Ranking] AS
RANK ([Row Axis].CurrentMember,[Portfolios], [Measures].[FormattedBarraoutput])
SELECT
{[Measures].[FormattedBarraoutput],[Measures].[Ranking]} ON COLUMNS
,[Row Axis] ON ROWS
FROM [wobbly_woo]
WHERE
(
[Time].[TimeKey].&[20120131]
);

Related

How can I fix the error: A set has been encountered that cannot contain calculated members

Apologies in advance - I'm not very au fait with MDX
I am wanting to show the previous period variance of a measure.
I’ve tried using the following code in the Cube Calculations section :-
CREATE MEMBER CURRENTCUBE.[Analysis Period].[Relative Time].[Previous Period]
AS
null,
VISIBLE = 1;
SCOPE
(
[Analysis Period].[Relative Time].[Previous Period],
[Analysis Period].[Period to Date].ALLMEMBERS
);
SCOPE
(
DESCENDANTS
(
[Calendar].[Calendar Hierarchy].[All],
[Calendar].[Calendar Hierarchy].[Year],
SELF_AND_AFTER
)
);
THIS =
(
[Calendar].[Calendar Hierarchy].PREVMEMBER,
[Analysis Period].[Relative Time].&[1]
);
END SCOPE;
END SCOPE;
CREATE MEMBER CURRENTCUBE.[Analysis Period].[Relative Time].[Variance PrevPd]
AS
(
[Analysis Period].[Relative Time].&[1] -
[Analysis Period].[Relative Time].[Previous Period]
),
VISIBLE = 1;
Using the following sample MDX query (generated by the SSMS Browser) :-
SELECT
NON EMPTY {[Measures].[Inflow]}
ON COLUMNS
FROM
(
SELECT
(
{[Analysis Period].[Relative Time].[Variance PrevPd]}
)
ON COLUMNS
FROM
(
SELECT
(
{[Calendar].[Calendar Month].&[202207]}
)
ON COLUMNS
FROM
(
SELECT
(
{[Fact Type].[Transactions or Holdings].&[Transactions]}
)
ON COLUMNS
FROM [Finscape]
)
)
)
WHERE
(
[Fact Type].[Transactions or Holdings].&[Transactions],
[Calendar].[Calendar Month].&[202207],
[Analysis Period].[Relative Time].[Variance PrevPd]
)
This returns the error :-
A set has been encountered that cannot contain calculated members.
Google searches indicate that this is related to the use of scope / end scope statements and recommend re-formatting the calculations to remove them – I have tried this, but with everything I tried, I still get the same error.
I’ve now reached the limit of my MDX knowledge and need a steer – can anyone help?

SSRS: Open report with long URL parameters in new window

I have question similar as Open SSRS URL in New Window, but one of my parameters has many values and the URL becomes too long. This parameter always equals such parameter in initial report.
How can I solve it? Can I make post request in "go to url" field or define parameter default value from initial report?
Here is how I reduce the amount of characters passed into my report URL with parameters. Since Microsoft Internet Explorer has a maximum uniform resource locator (URL) length of 2,083 characters you have to get creative.
First, add parameter values for all variables. The other option would be to use a defaults table.
Then union the parameter(s) to the datasets for your other parameters. This way you'll get the all option in your parameter dropdowns.
;WITH
teams_source
AS
(
SELECT tbl.* FROM (VALUES
( 2323304)
, ( 2323305)
, ( 2323306)
, ( 2323307)
, ( 2323308)
, ( 2323309)
, ( 2323310)
, ( 2323311)
, ( 2323312)
, ( 2323313)
, ( 2323314)
, ( 2323315)
, ( 2323316)
) tbl ([Teams])
)
SELECT [Teams], [TeamsFormat] = CAST([Teams] AS VARCHAR) FROM teams_source
UNION
SELECT [Teams] = #all_value_nbr, [TeamsFormat] = #all_value_text
ORDER BY 1
Then in the dataset for your report change the WHERE clause to check for the all variable.
WHERE
1=1
AND (#all_value_nbr IN(#Teams) OR [Teams] IN(#Teams))
When you build the URL with parameters, you can count the number of values.
IIF(Parameters!Teams.Count = Count(Fields!Teams.Value, "TeamsDataset"), "", "#Teams=" + Join(Parameters!Teams.Value, "#Teams="))

The STRTOSET function expects a tuple set expression for the 1 argument. A string or numeric expression was used

I'm using reporting services, using parameters, so I have query like this:
SELECT
NON EMPTY { [Measures].[ReclamosBSC_Reclamos] } ON COLUMNS,
NON EMPTY { ([Dim_Tiempo_].[Anio].[Anio].ALLMEMBERS
* [Dim_Tiempo_].[Mes].[Mes].ALLMEMBERS
* [Dim_Tiempo_].[NombreMesAbreviado].[NombreMesAbreviado].ALLMEMBERS
* [Dim_PlantaCentro_].[IdGrupo].[IdGrupo].ALLMEMBERS
* [Dim_PlantaCentro_].[NombreGrupo].[NombreGrupo].ALLMEMBERS
* [Dim_PlantaCentro_].[IdDivision].[IdDivision].ALLMEMBERS
* [Dim_PlantaCentro_].[NombreDivision].[NombreDivision].ALLMEMBERS
* [Dim_PlantaCentro_].[IdPlanta].[IdPlanta].ALLMEMBERS
* [Dim_PlantaCentro_].[Planta].[Planta].ALLMEMBERS
* [Dim_ClientePadre_].[Dim_ClientePadre_].[Dim_ClientePadre_].ALLMEMBERS ) }
DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_VALUE, MEMBER_UNIQUE_NAME ON ROWS
FROM
(
SELECT
( STRTOSET(#DimTiempoMes) ) ON COLUMNS
FROM
(
SELECT
( STRTOSET(#DimTiempoAnio) ) ON COLUMNS
FROM
[BSC]
)
)
CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS
It runs correctly when I use query designer, but when I try to see Preview of my report it returns:
The STRTOSET function expects a tuple set expression for the 1
argument. A string or numeric expression was used.
Can someone explain me what is wrong with my query?
Assuming that the Preview functionality is setting your year and month parameter values to "2017" and "9", respectively, you can rewrite your query as follows:
SELECT
NON EMPTY { [Measures].[ReclamosBSC_Reclamos] } ON COLUMNS,
NON EMPTY { ([Dim_Tiempo_].[Anio].[Anio].ALLMEMBERS
* [Dim_Tiempo_].[Mes].[Mes].ALLMEMBERS
* [Dim_Tiempo_].[NombreMesAbreviado].[NombreMesAbreviado].ALLMEMBERS
* [Dim_PlantaCentro_].[IdGrupo].[IdGrupo].ALLMEMBERS
* [Dim_PlantaCentro_].[NombreGrupo].[NombreGrupo].ALLMEMBERS
* [Dim_PlantaCentro_].[IdDivision].[IdDivision].ALLMEMBERS
* [Dim_PlantaCentro_].[NombreDivision].[NombreDivision].ALLMEMBERS
* [Dim_PlantaCentro_].[IdPlanta].[IdPlanta].ALLMEMBERS
* [Dim_PlantaCentro_].[Planta].[Planta].ALLMEMBERS
* [Dim_ClientePadre_].[Dim_ClientePadre_].[Dim_ClientePadre_].ALLMEMBERS ) }
DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_VALUE, MEMBER_UNIQUE_NAME ON ROWS
FROM
(
SELECT
{ ( STRTOMEMBER('[Dim_Tiempo_].[Mes].[Mes].[' + #DimTiempoMes + ']') ) } ON COLUMNS
FROM
(
SELECT
{ ( STRTOMEMBER('[Dim_Tiempo_].[Anio].[Anio].[' + #DimTiempoAnio + ']') ) } ON COLUMNS
FROM
[BSC]
)
)
CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS
Using nested subqueries will allow you to include the year and month on your ROWS axis in the SELECT clause. If you used a WHERE clause, you would get an error when including the year and month in the SELECT clause.

MDX Query with parameters with multiples values and null value

I work with a SSAS Cube and Datazen (dashboard creator). I've a data view (for the valueCode 'AZE') with 3 parameters:
AgeClassCode: 'AGE01', 'AGE02', 'AGE03', ...
StatutCode: 'A', 'B', 'C', 'D', ...
NiveauCode: 'X', 'Y', 'W', ...
With this query, when I use multiple values or just one value for each, it works.
But I would like that the query returns all values for a parameter when the parameter's value is null. I've tested ISEMPTY(#param), ISEMPTY(STRTOSET(#param)), ... but that returns this error:
An mdx expression was expected. An empty expression was specified.
This query works for one or more values:
SELECT
NON EMPTY
{
[Measures].[Value], [Measures].[PreviousValueYear], [Measures].[PreviousValueReportMonth]
} ON COLUMNS,
NON EMPTY
{
NONEMPTY
(
[EntiteFederal].[ServiceCode].[ServiceCode].ALLMEMBERS *
[EntiteFederal].[EntiteCode].[EntiteCode].ALLMEMBERS *
[ReportMonth].[ReportMonth].[ReportMonth].ALLMEMBERS *
[T].[Year].[Year].ALLMEMBERS
)
} DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS
FROM
(
SELECT ( { [ValueType].[ValueCode].&[AZE] } ) ON COLUMNS
FROM (
SELECT ( STRTOSET('{{ #AgeClassCode }}') ) ON COLUMNS
FROM (
SELECT ( STRTOSET('{{ #NiveauCode }}') ) ON COLUMNS
FROM
(
SELECT ( (STRTOSET('{{ #StatutCode }}') ) ON COLUMNS
FROM [MyCube]
)
)
)
)
WHERE
(
IIF( STRTOSET('{{ #StatutCode }}').Count = 1, STRTOSET('{{ #StatutCode }}'), [Statut].[StatutCode].currentmember ),
IIF( STRTOSET('{{ #NiveauCode }}').Count = 1, STRTOSET('{{ #NiveauCode }}'), [Niveau].[NiveauCode].currentmember ),
IIF( STRTOSET('{{ #AgeClassCode }}').Count = 1, STRTOSET('{{ #AgeClassCode }}'), [AgeClass].[AgeClassCode].currentmember ),
[ValueType].[ValueCode].&[AZE]
)
What do I have to change?
EDIT:
To test the strtoset()
, the good solution is the
isError()
When using strToSet or strToMember you need to supply a string that represents valid mdx so for example these are ok:
strToSet("[AgeClassCode].[AgeClassCode].members")
strToMember("[AgeClassCode].[AgeClassCode].[AGE01]")
This isn't valid as NULL isn't a string, or something that represents mdx:
strToSet(NULL)
So if in your client you'd like NULL to represent all members then somehow you need to transform the NULL to a string "[AgeClassCode].[AgeClassCode].members" before it hits strToSet.

SSAS -> KPI Creation -> How to create a kpi that compares the rank of a customer on one day compared to the previous day?

I have been working on creating a kpi that compares the rank of a customer on a specific date compared to the previous day. In turn you would be able to see if that customer has went up in rank or down in rank in terms of whatever the list was generated by. In my situation they are ordered by revenue.
I am able to rank my customers via the rank function easily enough and provide the report but when it comes to creating the kpi of comparing these ranks across days I am struggling in figuring out how this should be approached. The rank itself is not something stored as data it is something that I will need to create on the fly via the rank function.
Here is an example of my mdx query that I am using to create my initial starting report that provides me with rank of customers without a date splice:
WITH SET [RevRank] AS
ORDER (
[Customer].[Customer Id].CHILDREN ,
[Measures].[Revenue], BDESC)
MEMBER [Measures].[RANKRevenue] AS RANK([Customer].[Customer Id].CurrentMember, [RevRank] )
SELECT NON EMPTY { [Measures].[Revenue], [Measures].[Fact Order Count], [Measures].[RANKRevenue] } ON COLUMNS,
NON EMPTY TopCount( { ([RevRank] ) } , 100, [Measures].[Revenue]) ON ROWS
FROM [DW]
From this I am attempting to splice in a specific date (day) and then compare that rank to a previous day within a kpi. So, starting off I am working on breaking this query up. I created a pre calculated set and pre calculated member to help me do this more easily. Now I am just trying to figure out how to create this set and member by a day and then I can at least produce a comparison between one day and the next.
01/26/2012 Update: Ok, I am a bit further down the road on this, but I am still having issues with getting the rank to pull into my query, the query below has nulls for the rankings. Hopefully someone can see the issue with this query.
WITH MEMBER [Measures].[PrevDayRevenue] AS
( [Measures].[Revenue], ParallelPeriod ([Date Link].[PK Date].[PK Date],1))
SET [RevRankPrevOrder] AS
ORDER (
[Customer].[Customer Id].Members ,
[Measures].[PrevDayRevenue],
BDESC)
MEMBER [Measures].[RANKRevenuePrevOrder] AS RANK([Customer].CurrentMember, [RevRankPrevOrder])
SET [RevRankCurrOrder] AS
ORDER (
[Customer].[Customer Id].Members ,
[Measures].[Revenue],
BDESC)
MEMBER [Measures].[RANKRevenueCurrOrder] AS RANK([Customer].CurrentMember, [RevRankCurrOrder])
SELECT NON EMPTY { [Measures].[Revenue], [Measures].[PrevDayRevenue], [Measures].[RANKRevenuePrevOrder], [Measures].[RANKRevenueCurrOrder] } ON COLUMNS,
NON EMPTY { ( [RevRankCurrOrder] ) } ON ROWS
FROM [DW]
WHERE {[Date Link].[PK Date].&[2012-01-08T00:00:00]}
You can use the ParallelPeriod function to calculate the rank for the prior day. This will also need to be done on the fly.
Then you can just compare the two in your KPI value...
CASE
WHEN [Customer Rank Yesterday] - [Customer Rank Today] > 0 THEN 1
WHEN [Customer Rank Yesterday] - [Customer Rank Today] = 0 THEN 0
ELSE -1
END
Here is my finished query, hope this helps someone else. :
WITH MEMBER [Measures].[PrevDayRevenue] AS
( [Measures].[Revenue], ParallelPeriod ([Date Link].[PK Date].[PK Date],1))
SET [RevRankPrevOrder] AS
ORDER (
[Customer].[Customer Id].CHILDREN ,
[Measures].[PrevDayRevenue],
BDESC)
MEMBER [Measures].[RANKRevenuePrevOrder] AS
RANK(
[Customer].[Customer Id].CurrentMember,
[RevRankPrevOrder])
SET [RevRankCurrOrder] AS
ORDER (
[Customer].[Customer Id].CHILDREN,
[Measures].[Revenue],
BDESC)
MEMBER [Measures].[RANKRevenueCurrOrder] AS RANK([Customer].[Customer Id].CurrentMember, [RevRankCurrOrder])
SELECT NON EMPTY { [Measures].[Revenue], [Measures].[PrevDayRevenue], [Measures].[RANKRevenuePrevOrder], [Measures].[RANKRevenueCurrOrder] } ON COLUMNS,
NON EMPTY { ( [RevRankCurrOrder] ) } ON ROWS
FROM [DW]
WHERE {[Date Link].[PK Date].&[2012-01-10T00:00:00]}

Resources