Changes between Initial Version and Version 1 of AdvancedReports


Ignore:
Timestamp:
06/14/26 21:20:58 (2 days ago)
Author:
213257
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedReports

    v1 v1  
     1= Advanced Reports =
     2
     3== Unit Demand Forecast — Quarterly Interest Ranking ==
     4
     5Which currently available units show the strongest demand signals in the last quarter,
     6and which buildings are generating the most interest for units.
     7Each unit is scored by the inquiry count, appointment count. The units are ranked within their building,
     8with the goal to give insight into potential buyer interest in what types of flats potential buyers are mostly looking for.
     9
     10=== SQL ===
     11
     12{{{
     13WITH unit_stats AS (
     14    SELECT
     15        u.unit_id,
     16        u.unit_number,
     17        u.price,
     18        u.room_number,
     19        u.floor_area,
     20        f.floor_number,
     21        b.building_id,
     22        b.name                            AS building_name,
     23        COUNT(DISTINCT i.inquiry_id)      AS total_inquiries,
     24        COUNT(DISTINCT a.appointment_id)  AS total_appointments,
     25        ROUND(
     26            COUNT(DISTINCT a.appointment_id)::NUMERIC /
     27            NULLIF(COUNT(DISTINCT i.inquiry_id), 0) * 100, 2
     28        )                                 AS conversion_rate_pct
     29    FROM project.unit u
     30    JOIN project.floor f ON u.floor_id = f.floor_id
     31    JOIN project.building b ON f.building_id = b.building_id
     32    LEFT JOIN project.inquiry i ON u.unit_id = i.unit_id
     33        AND i.created_at >= CURRENT_DATE - INTERVAL '3 months'
     34    LEFT JOIN project.appointment a  ON u.unit_id = a.unit_id
     35        AND a.status = 'Scheduled'
     36    LEFT JOIN project.timeslot ts ON a.timeslot_id = ts.timeslot_id
     37        AND ts.date >= CURRENT_DATE - INTERVAL '3 months'
     38    WHERE u.status = 'Available'
     39    GROUP BY
     40        u.unit_id, u.unit_number, u.price, u.room_number, u.floor_area,
     41        f.floor_number, b.building_id, b.name
     42)
     43SELECT
     44    building_name,
     45    unit_number,
     46    floor_number,
     47    room_number,
     48    floor_area,
     49    price,
     50    total_inquiries,
     51    total_appointments,
     52    conversion_rate_pct,
     53    (total_inquiries + total_appointments * 2)  AS interest_score,
     54    RANK() OVER (
     55        PARTITION BY building_id
     56        ORDER BY (total_inquiries + total_appointments * 2) DESC
     57    )                                           AS rank_in_building
     58FROM unit_stats
     59ORDER BY interest_score DESC, building_name, rank_in_building;
     60}}}
     61
     62=== Relational Algebra ===
     63
     64Selection of available units and joining to floor and building
     65
     66{{{
     67AvailableUnits ← σ(status = 'Available')(Unit)
     68
     69UnitFloorBuilding ← AvailableUnits
     70    ⋈(unit.floor_id = floor.floor_id) Floor
     71    ⋈(floor.building_id = building.building_id) Building
     72}}}
     73
     74Selecting recent inquires and scheduled appointments
     75
     76{{{
     77RecentInquiries ← σ(created_at ≥ CURRENT_DATE − 90)(Inquiry)
     78
     79RecentScheduledAppts ← σ(appointment.status = 'Scheduled' ∧ timeslot.date ≥ CURRENT_DATE − 90)(
     80    Appointment ⋈(appointment.timeslot_id = timeslot.timeslot_id) Timeslot
     81)
     82}}}
     83
     84Left joining units to the inquires and appointments and per unit aggregation
     85
     86{{{
     87UnitWithActivity ← UnitFloorBuilding
     88    ⟕(unit.unit_id = inquiry.unit_id) RecentInquiries
     89    ⟕(unit.unit_id = appointment.unit_id) RecentScheduledAppts
     90
     91UnitStats ← γ(
     92    unit_id, unit_number, price, room_number, floor_area,
     93    floor_number, building_id, name ;
     94    COUNT(inquiry_id)     → total_inquiries,
     95    COUNT(appointment_id) → total_appointments,
     96    COUNT(appointment_id) / NULLIF(COUNT(inquiry_id), 0) * 100
     97                          → conversion_rate_pct
     98)(UnitWithActivity)
     99}}}
     100
     101Interest score, ranking within building, and final columns
     102
     103{{{
     104Scored ← ρ(
     105    interest_score   ← total_inquiries + total_appointments · 2,
     106    rank_in_building ← RANK() OVER (PARTITION BY building_id
     107                                    ORDER BY interest_score DESC)
     108)(UnitStats)
     109
     110Result ← τ(interest_score DESC, name, rank_in_building)(Scored)
     111
     112π(name, unit_number, floor_number, room_number, floor_area,
     113  price, total_inquiries, total_appointments,
     114  conversion_rate_pct, interest_score, rank_in_building)(Result)
     115}}}
     116
     117----