Descendants to selected only - sql-server

The Product Hierarchy consists of 3 levels:
Category,
SubCategory
and Product
I have firstly created a dynamic set [Selected Products]:
CREATE DYNAMIC SET [Selected Products] as (
EXISTING [Product].[Product].members - [Product].[Product].[All]
);
I have a measure_ that is calculated as follows:
CREATE MEMBER CURRENTCUBE.[MEASURES].[MyMeasure(%)_]
AS IIF([Measures].[Total] <> 0, [Measures].[SomeMeasure]/[Measures].[Total], NULL)
and it is used to calculate the following measure:
CREATE MEMBER CURRENTCUBE.[MEASURES].[MyMeasure(%)]
AS
(
IIF(
[Product].[Product Hierarchy].CurrentMember IS [Product].[Product Hierarchy].[All]
,AVG([Selected Products],[MEASURES].[MyMeasure(%)_]),
AVG(Descendants([Product].[Product Hierarchy].currentmember,[Product].[Product Hierarchy].Levels('Product'),SELF)
, [MEASURES].[MyMeasure(%)_])
)
)
Grand total calclation is fine as it takes all the [Selected Products]
Calculation on Product level is also fine.
The problem is when it comes to calculate on Category or SubCategory level when not all belonging products are selected. The returned values in fact are calculations for all belonging children and not selected only.
Is is possible to amend above Descendants() expression so it refers to [Selected Products] only?
How can I re write?

Related

SQL - Remove Duplicates

I've inherited data from another provider and have 2 tables to clean up
Rooms
Items
Items are within a Room and are linked via Rooms.RoomID / Items.RoomID
Each time an Item has been inspected it has created a Duplicate of the Room & Item, so I have 6 records for each Room and each Item (Each with a unique RoomID, so 1 to 1)
My aim is to remove the Duplicate Rooms and keep only the latest set of records, then update the Items table with the RoomID (So I have 1 to Many i.e. 1 Room with 6 Item records)
I can GROUP the Rooms and obtain the MAX RoomID but don't know how to do the UPDATE
A kind of suedo would be this:
UPDATE a
SET a.RoomID = MAX(b.RoomID)
FROM [dbo].[tmp_Items] a
inner join [dbo].[tmp_Rooms] b on b.PropertyID = a.PropertyID
and b.FloorLevel = a.FloorLevel
and b.Reference = a.Reference
The combination of PropertyID, FloorLevel, and Reference provides a unique link between Items and Rooms as these columns are in both tables and Reference is unique to each floor of a property (Each Room of each Floor is numbered starting from 1)
Any help or guidance appreciated :)
Use a subquery to aggregate before joining:
UPDATE i
SET i.RoomID = r.max_roomid
FROM [dbo].[tmp_Items] i JOIN
(SELECT PropertyID, FloorLevel, Reference, MAX(r.RoomID) as max_roomid
FROM [dbo].[tmp_Rooms] r
GROUP BY PropertyID, FloorLevel, Reference
) r
ON r.PropertyID = i.PropertyID AND
r.FloorLevel = i.FloorLevel AND
r.Reference = i.Reference;

MDX Percentage Row Not Calculating Correctly

I am trying to calculate a percentage row in a table based on a total column derived earlier in the query.
There are two columns then I create a total for that column. In the next row I want a percentage of the total to show. The output should be something like:
Life Non-Life (P&C) SumTotal
Premiums 66,104.44 916,792.51 982,896.95
Percentage 6.73% 93.27% 1
But instead the second line shows zero.
How do I structure the query to calculate correctly?
Here is the mdx code:
with member [LocationSpecificClass].[Hierarchy].[All].&[Insurance Market Statistics].[SumTotal] as SUM([LocationSpecificClass].[Hierarchy].[All].&[Insurance Market Statistics] , [Measures].[Value] )
member [LocationSpecificData].[Data Type].[All].[Percentage] as [LocationSpecificData].[Data Type].[All].[Gross Written Premiums Total - Calculated], [Measures].[Value] ) / ([LocationSpecificClass].[Hierarchy].[All].&[Insurance Market Statistics].[SumTotal], [Measures].[Value] )
Select { [LocationSpecificClass].[Hierarchy].[All].&[Insurance Market Statistics].&[Life], [LocationSpecificClass].[Hierarchy].[All].&[Insurance Market Statistics].&[Non-Life (P&C)], [LocationSpecificClass].[Hierarchy].[All].&[Insurance Market Statistics].[SumTotal] } On Columns ,
{ [LocationSpecificData].[Data Type].[All].[Gross Written Premiums Total - Calculated] , [LocationSpecificData].[Data Type].[All].[Percentage] } On Rows
FROM [CubeDatabase]
Please try the following example, which worked fine in my environment. I've used our date dimension [Datum] with the year attribute [Jahr] to add a second a line by adding [Line2]. The first shown line is the year 2016. Set the calculated measures [M1] and [M2] to your needs and exchange the year dimension accordingly.
WITH
MEMBER [Measures].[M1] AS [Measures].[name of your measure for col 1]
MEMBER [Measures].[M2] AS [Measures].[name of your measure for col 2]
MEMBER [Measures].[Total] AS [Measures].[M1] + [Measures].[M2]
MEMBER [Datum].[Jahr].[Line2] AS
Divide(
([Datum].[Jahr].&[2016], [Measures].CurrentMember),
([Datum].[Jahr].&[2016], [Measures].[Total])
)
SELECT {
[Measures].[M1],
[Measures].[M2],
[Measures].[Total]
} ON 0,
{
[Datum].[Jahr].&[2016],
[Datum].[Jahr].[Line2]
} ON 1
FROM [name of cube]
The result in my environment looks like this:

How to write MDX Query for getting grouped results

I have Cube where data is aggregated and all I need to have count of records against each 2 digit zip code.
Attached image shows my cube hierarchies and measures.
I applied query like :
WITH MEMBER [Measures].NoOfConsignments as Count(([Consignment].[Target Address Name].[Target Address Name]))
select filter([Consignment].[Distribution Area].[Zip2], [Consignment].[Distribution Area].[Target Address Country] = "94") on rows,
{[Measures].NoOfConsignments} on columns
from [RebellOlap]
where ({[Consignment].[Distribution Area].[Target Address Country].&[94]})
but is throwing an error :
"The Distribution Area hierarchy already appears in the Axis1 axis"
I re-structured and formulated following sub-select query in the following way :
WITH MEMBER [Measures].NoOfConsignments as Count(([Consignment].[Target Address Name].[Target Address Name]))
Select
NON EMPTY [Measures].NoOfConsignments on columns,
NON EMPTY [Consignment].[Distribution Area].[Zip2] on rows
FROM (
SELECT {[Consignment].[Distribution Area].[Zip2],[Consignment].[Distribution Area].[Target Address Country].&[94]}
FROM [RebellOlap]
)
but it also returned me the 'ambiguity error'.
all I need Output in following manner
Edit
AllConsignments in Germany
All Consignments in Germany against specific Zip Code
I just applied filter for all zip codes and introduce "Range" as Operator with 'Filter Expression' and it worked!!
SELECT NON EMPTY { [Measures].[ConsignmentCount] } ON COLUMNS,
NON EMPTY { ([Consignment].[Distribution Area].[Zip2].ALLMEMBERS ) } ON ROWS
FROM ( SELECT ( [Consignment].[Distribution Area].[Zip2].&[94]&[0]&[01] : [Consignment].[Distribution Area].[Zip2].&[94]&[9]&[99] ) ON COLUMNS
FROM [RebellOlap])
Based on your edits, I feel below should work out for you:
WITH MEMBER Measures.NumConsignment as
COUNT
(
NonEmpty
(
[Consignment].[Target Address Name].[Target Address Name].MEMBERS,
([Consignment].[Distribution Area].CURRENTMEMBER, Measures.[Num. Consignments])
)
)
SELECT [Consignment].[Distribution Area].[Zip2].MEMBERS on 1,
Measures.NumConsignment ON 0
FROM
(
SELECT [Consignment].[Distribution Area].[Target Address Country].&[94] ON 0
FROM [RebellOlap]
)
While the rest of the code is pretty standard, there is one part which might need explanation.
NonEmpty
(
[Consignment].[Target Address Name].[Target Address Name].MEMBERS,
([Consignment].[Distribution Area].CURRENTMEMBER, Measures.[Num. Consignments])
)
This is returning a set of those Target addresses for the current zip for whom the num of consignments is not empty( i.e. <>0)

MDX query to filter dimension on metric values

I want to filter out dimensions if the metric values not exist over that dimension, but I have some metric containing some raw data ie, Infinity, 1.#NN.
I am using NON EMPTY() but it is not filtering data correctly as it filter the dimension if all metrics are null but in my case it fetch 'Infinity' dimensions too:
Mdx Query:
SELECT
{
[Measures].[1],
[Measures].[2],
[Measures].[3]
} DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS
, NON EMPTY Hierarchize (
{
DrilldownLevel ( { [Roles].[Dimension].[All] } )
}
) DIMENSION PROPERTIES PARENT_UNIQUE_NAME
, [Roles].[Roster Role].[Roster Role].[Roster Role - Enterprise]
, [Roles].[Roster Role].[Roster Role].[Roster Role - Group] ON ROWS
FROM [Cuve]
WHERE ( [Dates].[Calendar].[Calendar Year].&[2013], [Markets].[Market].&[1], [Areas]. [Area].&[8], [Roles].[Enterprise Role].&[2] )
I can not NONEMPTY() as it remove dimension if any of metric is null while I want to remove if all are null.
I want that I can filter out dimension, ie if metric value is not an integer (eg, "Infinity" or other data) or filter it out by NOT IN() kind of function.
Thanks
First, it sounds like you are dividing by 0 in the calculations for your measures. If you can, I would rewrite them to return null where the denominator is 0.
This would look something like:
IIF([Measures].[denominator] = 0, Null, [Measures].[Numerator/[Measures].[Denominator])
Then you can use Filter. I'm not quite sure I know enough about your cube's structure to write your query, but try something like this:
Select {
[Measures].[1],
[Measures].[2],
[Measures].3]} on COLUMNS,
{ Filter([Roles].[Dimension].[Dimension].members, CoalesceEmpty([Measures].[1],[Measures].[2],[Measures].[3], 0) <> 0)
* ({[Roles].[Roster Role].[Roster Role].[Roster Role - Enterprise], [Roles].[Roster Role].[Roster Role].[Roster Role - Group]})} on ROWS
FROM [Cuve]
WHERE ( [Dates].[Calendar].[Calendar Year].&[2013], [Markets].[Market].&[1], [Areas]. [Area].&[8], [Roles].[Enterprise Role].&[2] )

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