MDX - sum costs up to a given date - mdx

This is a slight modification of what I stumbled upon while searching the web:
Let's say I have a dimension PROJECTS which contains:
project_id - unique id
category - category of a cost
project_date - date of summing up the cost
My warehouse also has the dimension of TIME with date, and a dimension COSTS containing values of costs. Those three dimensions are connected by the measure group EXPENSES which has:
id_date
id_cost
id_project
I want to wirte an MDX query which would group the projects by their category, and sum up all the costs, but only those which do not exceed the date given in the project_date attribute of the dimension PROJECTS (each category has the same project_date, I know it's redundant but I can't change it..)

I'm not sure, but maybe something alongside this?
SELECT
[COSTS].[COST] ON 0,
[PROJECTS].[category] ON 1
FROM [CUBE]
WHERE
[PROJECTS].[project_date] < #project_date

Related

SSAS MDX Calculation - Sum based off a group value

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.

Webi SAP BO Sum in block depending on two dimensions

I am trying to sum every line in a table summarizing it by two fields in webi.
I have a table with the following columns:
Risk, Year, AssessedBy, Weight, Value.
I have filtered the table by Year = 2018 and Risk = "01". Thus, I only have the info for that year and that risk.
Each person assessing has a different weight in the final valuation by risk and year. What I have done is divide the assessing person's weight by the total sum of every Weight in the table [ sum(weight) in block ].
The problem is that when I delete the filter, the in block clause makes that the total sum of the weights changes to the total sum of the weights for every year in the table.
I would need something to calculate the total sum for each year and risk.
Just solved it! Just see Sumal Kunir answer: http://www.forumtopics.com/busobj/viewtopic.php?p=971131
=sum([Var_a] for each(Dimension;dimension)) In (Demension)
where var_a is the measure, foreach defines a background to base in and in defines the level at which you want to aggregate.

Distinctcount - suppliers for departments over a period of time - slow performance

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

Create MDX to Divide two measures for each month and then sum the all of the months

I have a multidimensional cube that needs a custom measure that I'm not sure how to build.
That data looks like this:
MemberID-----Date-------EventType
1--------------1/1/2016-------1
2--------------1/1/2016-------2
3--------------2/1/2016-------1
2--------------2/1/2016-------2
4--------------2/1/2016-------2
There is a count measure in the cube, but others can be added if needed. I need to create a measure that will use whatever filters the user applies and then count the EventType (1 and 2 only) by month, divide the resulting counts for EventType 1 into the count for EventType 2 (for each month individually), and finally sum the monthly results. For example 1/1/2016 would be 1/1=1 (count of EventType 1 and count of EventType 2) and 2/1/2016 would be 1/2=0.5 so the resulting measure value for the two months would be 1+0.5=1.5. Any help is greatly appreciated.
Let's assume you have a Date dimension with an attribute called Month. And let's assume you have an EventType dimension. And let's assume you have a count measure in your measure group called Cnt. Here's what else you need to do.
First, go to the DSV and add a new calculated column to the fact table which is called NullInt and is the following expression:
cast(null as int)
Then create a new Sum measure in your measure group off that column and call the measure My Rollup. Under the Source property, change NullHandling to Preserve so that it will start off null.
To explain why we're doing this, a scoped assignment to a physical measure will aggregate up. (If you assign a value to a physical measure at the grain of each month, then it will rollup to the grand total.) But a scoped assignment to a calculated measure doesn't roll up.
Then in your MDX script add the following calculations:
scope([Date].[Month].[Month].Members); //calculate at the month level then rollup
[Measures].[My Rollup] = DIVIDE(
([Event Type].[Event Type].&[1],[Measures].[Cnt]),
([Event Type].[Event Type].&[2],[Measures].[Cnt])
);
end scope;
Note that your version of SSAS probably has the DIVIDE function if it's AS2012 with the latest service pack or newer. But if it doesn't, you can always do division the old fashioned way as IIF(denom=0,null,num/denom).

Powerpivot sum from dimension table

I am a graduate intern at a big company and I'm having some trouble with creating a measure in PowerPivot.
I'm quite new with PowerPivot and I need some help. I am the first person to use PowerPivot in this office so I can't ask for help here.
I have a fact table that has basically all journal entries. See next table. All entries are done with a unique ID (serialnumber) for every product
ID DATE ACCOUNT# AMOUNT
110 2010-1-1 900 $1000
There is a dimension table with has all accounts allocated to a specific country and expense or revenue.
ACCOUNT# Expense Country
900 Revenue Germany
And another dimension table to split the dates.
The third dimension table contains product information, but also contains a column with a certain expense (Expense X).
ID Expense X ProductName Productcolour
110 $50 Flower Green
I made sure I made the correct relations between the tables of course. And slicing works in general.
To calculate the margin I need to deduct this expense x from the revenue. I already made a measure that shows total Revenue, that one was easy.
Now I need a measure to show the total for Expense X, related to productID. So I can slice in a pivot table on date and product name etc.
The problem is that I can't use RELATED function because the serial number is used multiple times in the fact table (journal entries can have the same serial number)
And if I use the SUM or CALCULATE function it won't slice properly.
So how can I calculate the total for expense X so it will slice properly?
Check the function RELATEDTABLE.
If you create a dummy dataset I can play around and send you a solution.