I'm pretty new to MDX, but am stuck supporting a new tool and have a question about a request that recently came my way. We have a cube of prescription data, where prescribers are assigned to different territories. My client wanted a function to calculate the number of prescribers assigned to a territory, so I produced this:
COUNT(
FILTER([M_Prescriber].[Prescriber].[Prescriber].Members*[Measures].[M-TRx],
[M_Market_Product].[Product].[All]
)
)
Which gives a count of prescribers who have written a prescription in the time period. The problem the client has is that this function produces a different result in each month because, naturally, some prescribers don't write prescriptions every month. Is there a way to return the number of prescribers assigned to a territory without taking into account whether they have any prescription data in a particular month. Or could I calculate this value in the latest time period and use that value in every time period?
Let me know if I can provide more details.
OK, if I understand correctly, you want to count the Prescriber members that are in each Territory, and you already have a hierarchy built that describes which Prescribers are in which Territory.
Here's an example against Adventure Works of how you could do it:
WITH MEMBER [Measures].[count] AS
Count([Customer].[Customer Geography].CurrentMember.Children)
SELECT
[Measures].[count] ON COLUMNS,
DrilldownLevel([Customer].[Customer Geography].[All Customers]) ON ROWS
FROM [Adventure Works];
results:
count
All Customers 6
Australia 5
Canada 6
France 17
Germany 6
United Kingdom 1
United States 36
This counts only the immediate children of each node (the provinces or states in the hierarchy), so the count for All Customers is not an aggregate of the counts of each country.
In your case, you would change the ROWS selection to be your Division -> District -> Territory level.
Hope that helps at least set you on the right track.
Related
I have a suicide data of 100 countries from year 1985-2016.
It has a column which contains, suicides/100k pop, which is basically suicide rate.
But the problem is that the data is divided in each year and then further in age groups and gender.
I want the overall top 10 countries with the highest suicides/100k pop.
I have attached a preview of the table.
I am not able to build a query since the data is divided for each year you can't sum the suicide rate for each year to find the overall suicide rate.
I work for a hotel company and I have set up a fact table with the granularity of a stay night for each guest, e.g. if a guest stays for 3 nights, there would be a row for each night of the stay.
What I am trying to do is create a measure for the occupancy percentage (rooms booked divided by available rooms).
I have a column in the fact table that says how many rooms the hotel has, but just summing up that value doesn't work because then it is just multiplying the number of rooms by the number of guests. So I need to sum up the total guests and then divide by the number of rooms that that particular hotel has. Does this make sense?
[Measures].[On The Books] / [Measures].[Rooms Available]
The SQL for this would this:
SELECT stay.PropertyKey, prop.RoomsAvailable, stay.StayDateKey, COUNT(stay.Confirmation) AS Confirmation,
CAST(COUNT(stay.Confirmation) AS DECIMAL(13,9)) / CAST(prop.RoomsAvailable AS DECIMAL(13,9)) AS OccupancyPercentage
FROM dbo.FactStayNight stay
INNER JOIN
(
SELECT DISTINCT PropertyKey, RoomsAvailable
FROM dbo.FactStayNight
) prop
ON stay.PropertyKey = prop.PropertyKey
GROUP BY stay.PropertyKey, stay.StayDateKey, prop.RoomsAvailable
Your fact table is good, apart from the column with total number of rooms. The fact row is at the granularity level "Room", but the total number of rooms is at granularity level "Entire Hotel".
(You can imagine a "Real estate assets" hierarchy dimension, assuming you don't have one:
Hotel
Floor
Room
)
Possible solutions:
Add a "number of rooms" available in your Date dimension, at the Day level (strictly, "Night" level). This will sum commensurably with COUNT(Guests staying on that day). You could even adjust this number to reflect e.g. rooms under repair in particular periods.
You could implement a Room dimension, with each guest's Fact_NightStayed assigned to a Room. Then make what is technically called a "headcount" table, just like your Fact_NightStayed. But this table would be a "roomcount" table: a row indicates that a room exists on a particular day (or, if you decide, that a room exists and is usable i.e. not broken/being repaired). Pre-populate this table with one row per room per date, into the future up to a date you decide (this would be an annual refresh process). Then, joining Fact_NightStayed to Fact_RoomCount, your measure would be COUNT(NightStayed)/COUNT(RoomCount).
Watch out for aggregating this measure (however you implement it) over time: the aggregation function itself from the Day leaf level up the Date hierarchy should be AVG rather than SUM.
In a model that contains the following dimensions:
- Time - granularity month - 5 years - 20 quarters - 60 months
- Suppliers- 6000 suppliers at lowest level
- departments - 500 departments on lowest level
I need to have the distinct count of the suppliers for each department.
I use the function:
with member [measures].[#suppliers] as
distinctcount(([Supplier].[Supplier].[supplier].members
,[Measures].[amount]))
)
select [Measures].[#suppliers] on 0
, order([Department].[Department].[department].members, [#suppliers], BDESC) on 1
from [cube]
where [Time].[Time].[2017 10]:[Time].[Time].[2018 01]
The time component may vary, as the dashboard user is free to choose a reporting period.
But the MDX is very slow. It takes about 38ms to calculate the measure for each row. I want to use this measure to rank the departments and to calculate a cumulative % and assign scores to these values. As you can imagine performance will not improve.
I have tried to use functions and cache the result, but results - for me - got worse (according to the log 2x as bad).
What can I do to improve the performance?
To go fast adding a measure that calculates de Distinct Count on the Supplier ID of the table associated to[Measures].[Amount] will help. In the Schema definition.
The other ones are not scalable as Supplier is growing.
Nonetheless, why did you use DistinctCount instead of Count(NonEmpty())) ?
DistinctCount is mainly for calculating the number of members/tuples that are different in a set. It only makes sense if it's possible to have two same members in a set. As our initial members have no duplicated, it's useless.
Count(NonEmpty()) filters the set whith the nonempty and counts the number of items in the set. This can be easily calculated in parallel
In Tableau 10.3, I have two tables (derived from SQL queries): Return Reasons, which has one row per day + city + return reason, and 'Sales' has one row per day + city (and NOT by return reason, since obviously not all sales are returned.)
I have two rows in Return Reasons for 2017-10-01 in Seattle: $10 in returns for 'Bad Fit' and $20 in returns for 'Poor Quality'. The Sales table has a row for 2017-10-01 in Seattle with $1000.
I want to show a graph with, say, a stacked bar giving $10/$1000 (1% rate) for Bad Fit stacked with $20/$1000 (2% rate) for Poor Quality. I can graph the $10 and $20 separate from the $1000 of sales, but combining to get the rates has stumped me. Importantly, I don't just want to aggregate by day + city, but might also roll up by month (from day) and country (from city.)
Short of creating columns for each return reason, which isn't scalable (due to any number of reasons which could change at any time), any idea how to do this?
Duplicating Sales across the reason rows didn't seem to help me. (E.g.: I could add columns Sales to Return Reasons, JOINing on day + city, giving $1000 (duplicated) in each row. This would be fine if I only aggregated at the city + day level, but I want to aggregate both Sales + Reasons by month, country, etc.)
I am in a situation where I need to calculate Percentage for every fiscal year depending on distinct count of the rows.
I have achieved the distinct count (fairly simple task) for each year city-wise and reached till these 2 listings in cube.
The first listing is state wide distinct count for given year.
Second listing is city wise distinct count for given year with percentage based on state-wide count for that year for that city.
My problem is that I need to prepare a calculated member for the percentage column for each given year.
For eg, In year 2009, City 1 has distinct count of 2697 and percentage raise of 32.94%. (Formula used= 2697/8187 ).
I tried with ([Measures].[Distinct Count])/(SUM(ROOT(),[Measures].[Distinct Count])) but no luck.
Any help is highly appreciated.
Thanks in advance.
PS: City wide sum of year 2009 can never be equal to statewide distinct count of that year. This is because we are calculating the distinct count for city and state both.
You need to create a Region Hierarchy for this, like State -> City. The create a calculation like below. Then in the browser put your Hierarchy on the left and the sales and calculated percentage in values.
([Dim].[Region].CurrentMember, [Measures].[Salesamt]) /
iif(
([Dim].[Region].CurrentMember.Parent, [Measures].[Salesamt]) = 0,
([Dim].[Region].CurrentMember, [Measures].[Salesamt]),
([Dim].[Region].CurrentMember.Parent, [Measures].[Salesamt])
)