Changes between Initial Version and Version 1 of AdvancedReports


Ignore:
Timestamp:
07/03/26 12:59:15 (8 days ago)
Author:
223091
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedReports

    v1 v1  
     1= Advanced Reports =
     2
     3This page documents Phase P6 of the Room Reservation System project. The goal of this phase is to define and implement more complex analytical database reports using SQL. The reports are designed to provide a higher-level picture of the long-term operation of the reservation system.
     4
     5The project has one team member, therefore two advanced analytical reports are implemented.
     6
     7The reports are based on the relational schema created in Phase P2 and confirmed through the normalization process in Phase P5.
     8
     9== Report 1: Quarterly room utilization and approval report ==
     10
     11=== Data requirements description ===
     12
     13This report analyzes how rooms are used over a longer period of time. It groups reservations by quarter, building, and room, and calculates the number of reservation requests, the number of approved, rejected, cancelled, and pending reservations, the total requested hours, and the approved reservation hours.
     14
     15The report is useful for identifying:
     16
     17* which rooms are used most often,
     18* which rooms have the highest approved reservation time,
     19* how much demand exists for each room,
     20* whether some rooms are frequently requested but not approved,
     21* which rooms are important resources in the organization.
     22
     23This report can be used on a quarterly, annual, or multi-year level. In the current query, the report is shown for the year 2026.
     24
     25=== Solution SQL ===
     26
     27{{{
     28WITH reservation_base AS (
     29SELECT
     30b.building_id,
     31b.name AS building_name,
     32r.room_id,
     33r.room_code,
     34r.type,
     35r.capacity,
     36res.reservation_id,
     37res.status,
     38DATE_TRUNC('quarter', res.reservation_date)::date AS quarter_start,
     39EXTRACT(EPOCH FROM (res.end_time - res.start_time)) / 3600.0 AS duration_hours
     40FROM project.reservations res
     41JOIN project.rooms r
     42ON res.room_id = r.room_id
     43JOIN project.buildings b
     44ON r.building_id = b.building_id
     45WHERE res.reservation_date >= DATE '2026-01-01'
     46AND res.reservation_date < DATE '2027-01-01'
     47),
     48room_report AS (
     49SELECT
     50quarter_start,
     51building_name,
     52room_code,
     53type,
     54capacity,
     55COUNT(*) AS total_room_reservations,
     56COUNT(*) FILTER (WHERE status = 'approved') AS approved_reservations,
     57COUNT(*) FILTER (WHERE status = 'rejected') AS rejected_reservations,
     58COUNT(*) FILTER (WHERE status = 'cancelled') AS cancelled_reservations,
     59COUNT(*) FILTER (WHERE status = 'pending') AS pending_reservations,
     60ROUND(COALESCE(SUM(duration_hours), 0)::numeric, 2) AS requested_hours,
     61ROUND(COALESCE(SUM(duration_hours) FILTER (WHERE status = 'approved'), 0)::numeric, 2) AS approved_hours,
     62ROUND(
     63(100.0 * COUNT(*) FILTER (WHERE status = 'approved') / NULLIF(COUNT(*), 0))::numeric,
     642
     65) AS approval_rate_percent
     66FROM reservation_base
     67GROUP BY
     68quarter_start,
     69building_name,
     70room_code,
     71type,
     72capacity
     73)
     74SELECT
     75quarter_start,
     76building_name,
     77room_code,
     78type,
     79capacity,
     80total_room_reservations,
     81approved_reservations,
     82rejected_reservations,
     83cancelled_reservations,
     84pending_reservations,
     85requested_hours,
     86approved_hours,
     87approval_rate_percent,
     88RANK() OVER (
     89PARTITION BY quarter_start
     90ORDER BY approved_hours DESC, total_room_reservations DESC, capacity DESC
     91) AS utilization_rank_in_quarter
     92FROM room_report
     93ORDER BY
     94quarter_start,
     95utilization_rank_in_quarter,
     96building_name,
     97room_code;
     98}}}
     99
     100=== Explanation of the SQL solution ===
     101
     102The query first creates a temporary result named ''reservation_base''. This part joins reservations, rooms, and buildings, and calculates the duration of each room reservation in hours.
     103
     104The second temporary result, ''room_report'', groups the data by quarter, building, room, room type, and capacity. It calculates aggregate values such as the total number of room reservations, the number of approved reservations, the number of rejected reservations, the number of cancelled reservations, the number of pending reservations, the total requested hours, and the approved hours.
     105
     106The final SELECT adds a ranking value using the SQL window function RANK(). Rooms are ranked inside each quarter according to approved reservation hours, number of reservations, and capacity.
     107
     108This makes the report analytical because it combines joins, filtering, grouping, conditional aggregation, duration calculation, and window ranking.
     109
     110=== Solution Relational Algebra ===
     111
     112The following relational algebra expression uses extended relational algebra because the report requires grouping and aggregate functions.
     113
     114Let:
     115
     116* Reservations = Res
     117* Rooms = R
     118* Buildings = B
     119
     120First, create the joined reservation-room-building relation:
     121
     122{{{
     123RB =
     124σ_{reservation_date >= '2026-01-01' ∧ reservation_date < '2027-01-01'}
     125(
     126Res ⋈*{Res.room_id = R.room_id} R
     127⋈*{R.building_id = B.building_id} B
     128)
     129}}}
     130
     131Then calculate grouped room utilization statistics:
     132
     133{{{
     134RoomReport =
     135γ_{quarter(reservation_date), B.name, R.room_code, R.type, R.capacity;
     136COUNT(reservation_id) → total_room_reservations,
     137COUNT_{status = 'approved'}(reservation_id) → approved_reservations,
     138COUNT_{status = 'rejected'}(reservation_id) → rejected_reservations,
     139COUNT_{status = 'cancelled'}(reservation_id) → cancelled_reservations,
     140COUNT_{status = 'pending'}(reservation_id) → pending_reservations,
     141SUM(end_time - start_time) → requested_hours,
     142SUM_{status = 'approved'}(end_time - start_time) → approved_hours
     143}
     144(RB)
     145}}}
     146
     147Finally, extend the grouped relation with an approval rate and a quarterly utilization ranking:
     148
     149{{{
     150Result =
     151ρ_{approval_rate_percent, utilization_rank_in_quarter}
     152(RoomReport)
     153}}}
     154
     155The report preserves the meaning of the original relations because every joined tuple represents a reservation connected to exactly one room and one building.
     156
     157== Report 2: Quarterly equipment demand and replenishment report ==
     158
     159=== Data requirements description ===
     160
     161This report analyzes how often equipment is requested as part of reservations and compares that demand with the available equipment quantity in the system. It combines equipment from general stock and equipment assigned to specific rooms.
     162
     163The report is useful for identifying:
     164
     165* which equipment is requested most often,
     166* which equipment has high demand compared to available quantity,
     167* whether equipment demand increases or decreases between quarters,
     168* which equipment types should be considered for replenishment,
     169* whether the organization has enough available equipment for future reservations.
     170
     171This report can support planning and decision-making for equipment purchasing and resource management.
     172
     173=== Solution SQL ===
     174
     175{{{
     176WITH room_stock AS (
     177SELECT
     178equipment_id,
     179SUM(quantity) AS assigned_room_quantity
     180FROM project.room_equipment
     181GROUP BY equipment_id
     182),
     183equipment_demand AS (
     184SELECT
     185e.equipment_id,
     186e.name AS equipment_name,
     187e.stock_quantity,
     188COALESCE(rs.assigned_room_quantity, 0) AS assigned_room_quantity,
     189e.stock_quantity + COALESCE(rs.assigned_room_quantity, 0) AS total_registered_quantity,
     190DATE_TRUNC('quarter', res.reservation_date)::date AS quarter_start,
     191COUNT(DISTINCT re.reservation_id) AS reservations_with_equipment,
     192COALESCE(SUM(re.requested_quantity), 0) AS total_requested_quantity,
     193COALESCE(SUM(re.requested_quantity) FILTER (WHERE res.status = 'approved'), 0) AS approved_requested_quantity,
     194COALESCE(SUM(re.requested_quantity) FILTER (WHERE res.status = 'pending'), 0) AS pending_requested_quantity,
     195COALESCE(SUM(re.requested_quantity) FILTER (WHERE res.status = 'rejected'), 0) AS rejected_requested_quantity
     196FROM project.equipment e
     197LEFT JOIN room_stock rs
     198ON rs.equipment_id = e.equipment_id
     199LEFT JOIN project.reservation_equipment re
     200ON re.equipment_id = e.equipment_id
     201LEFT JOIN project.reservations res
     202ON res.reservation_id = re.reservation_id
     203WHERE res.reservation_date IS NULL
     204OR (
     205res.reservation_date >= DATE '2026-01-01'
     206AND res.reservation_date < DATE '2027-01-01'
     207)
     208GROUP BY
     209e.equipment_id,
     210e.name,
     211e.stock_quantity,
     212rs.assigned_room_quantity,
     213DATE_TRUNC('quarter', res.reservation_date)::date
     214),
     215equipment_analysis AS (
     216SELECT
     217*,
     218ROUND(
     219(total_requested_quantity::numeric / NULLIF(total_registered_quantity, 0)),
     2202
     221) AS demand_to_registered_quantity_ratio,
     222LAG(total_requested_quantity) OVER (
     223PARTITION BY equipment_id
     224ORDER BY quarter_start
     225) AS previous_quarter_requested
     226FROM equipment_demand
     227WHERE quarter_start IS NOT NULL
     228)
     229SELECT
     230quarter_start,
     231equipment_name,
     232stock_quantity,
     233assigned_room_quantity,
     234total_registered_quantity,
     235reservations_with_equipment,
     236total_requested_quantity,
     237approved_requested_quantity,
     238pending_requested_quantity,
     239rejected_requested_quantity,
     240COALESCE(previous_quarter_requested, 0) AS previous_quarter_requested,
     241total_requested_quantity - COALESCE(previous_quarter_requested, 0) AS requested_quantity_change,
     242demand_to_registered_quantity_ratio,
     243CASE
     244WHEN demand_to_registered_quantity_ratio >= 1 THEN 'high demand - consider replenishment'
     245WHEN demand_to_registered_quantity_ratio >= 0.5 THEN 'medium demand'
     246ELSE 'low demand'
     247END AS demand_assessment
     248FROM equipment_analysis
     249ORDER BY
     250quarter_start,
     251total_requested_quantity DESC,
     252equipment_name;
     253}}}
     254
     255=== Explanation of the SQL solution ===
     256
     257The query first calculates the total quantity of each equipment type that is assigned to rooms. This is done in the temporary result ''room_stock'' by grouping records from ''project.room_equipment''.
     258
     259The second temporary result, ''equipment_demand'', combines equipment, room stock, requested equipment, and reservations. It calculates the number of reservations that requested each equipment type, the total requested quantity, and the requested quantity by reservation status.
     260
     261The third temporary result, ''equipment_analysis'', calculates the demand-to-available-quantity ratio and uses the LAG() window function to compare current quarter demand with previous quarter demand.
     262
     263The final SELECT returns the equipment demand analysis and adds a textual demand assessment. If the requested quantity is greater than or equal to the total registered quantity, the report marks the equipment as high demand and suggests replenishment.
     264
     265This makes the report analytical because it combines multiple relations, grouping, conditional aggregation, stock comparison, trend comparison, and decision-oriented classification.
     266
     267=== Solution Relational Algebra ===
     268
     269The following relational algebra expression uses extended relational algebra because the report requires grouping, aggregate functions, and trend comparison.
     270
     271Let:
     272
     273* Equipment = E
     274* !RoomEquipment = REqRoom
     275* !ReservationEquipment = REqRes
     276* Reservations = Res
     277
     278First, calculate how much equipment is assigned to rooms:
     279
     280{{{
     281RoomStock =
     282γ_{equipment_id;
     283SUM(quantity) → assigned_room_quantity
     284}
     285(REqRoom)
     286}}}
     287
     288Then join equipment with room stock, requested equipment, and reservations:
     289
     290{{{
     291EquipmentBase =
     292E ⟕*{E.equipment_id = RoomStock.equipment_id} RoomStock
     293⟕*{E.equipment_id = REqRes.equipment_id} REqRes
     294⟕_{REqRes.reservation_id = Res.reservation_id} Res
     295}}}
     296
     297Then group the data by quarter and equipment type:
     298
     299{{{
     300EquipmentDemand =
     301γ_{quarter(reservation_date), E.equipment_id, E.name, E.stock_quantity, assigned_room_quantity;
     302COUNT(REqRes.reservation_id) → reservations_with_equipment,
     303SUM(requested_quantity) → total_requested_quantity,
     304SUM_{status = 'approved'}(requested_quantity) → approved_requested_quantity,
     305SUM_{status = 'pending'}(requested_quantity) → pending_requested_quantity,
     306SUM_{status = 'rejected'}(requested_quantity) → rejected_requested_quantity
     307}
     308(EquipmentBase)
     309}}}
     310
     311Finally, extend the grouped relation with the demand ratio, previous quarter demand, and demand assessment:
     312
     313{{{
     314Result =
     315ρ_{total_registered_quantity,
     316demand_to_registered_quantity_ratio,
     317previous_quarter_requested,
     318requested_quantity_change,
     319demand_assessment}
     320(EquipmentDemand)
     321}}}
     322
     323The report preserves the meaning of the database model because equipment demand is calculated from !ReservationEquipment, while available equipment is calculated from Equipment and !RoomEquipment.
     324
     325== Final discussion ==
     326
     327The two implemented reports provide analytical information that is not directly visible from simple table contents.
     328
     329The first report focuses on room utilization. It helps identify which rooms are most frequently used and which rooms have the highest number of approved reservation hours. This can help the organization understand room demand and make better decisions about room scheduling and future room allocation.
     330
     331The second report focuses on equipment demand. It helps identify which equipment types are frequently requested and whether the current registered quantity is sufficient. This can help the organization decide whether certain equipment should be replenished or redistributed.
     332
     333Both reports are implemented with SQL queries over the normalized relational model from Phase P2 and Phase P5. No additional database tables are required because the existing schema already stores the necessary information about rooms, buildings, reservations, users, equipment, equipment assigned to rooms, and equipment requested in reservations.
     334
     335The reports can be reused in later phases as part of the application or as administrative database reports.