简体   繁体   中英

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, eg 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:

  1. 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 eg rooms under repair in particular periods.
  2. 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 ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM