Changes between Version 7 and Version 8 of P6


Ignore:
Timestamp:
05/13/26 20:52:40 (13 days ago)
Author:
193284
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P6

    v7 v8  
    1 = Phase 6: Complex Database Reports, SQL, Stored Procedures, and Relational Algebra
     1= Phase 6: Complex Database Reports, SQL, Stored Procedures, and Relational Algebra =
    22
    3 Overview
     3== Overview ==
    44
    5 In this phase we demonstrate how to extract, analyze and summarize data from the Wedding Planner database using advanced SQL. We focus on generating complex reports across multiple related tables, and implementing reusable logic through stored procedures and views.
    6 These techniques are important because in a real system the database is not used only for storing data, but also for producing meaningful insights (guest statistics, cost reports, utilization reports, timelines, etc.).
     5This phase demonstrates how the Wedding Planner database can be used for advanced reporting, analytical queries, stored procedures, and relational algebra representation.
    76
    8 SCENARIO 1: BUDGET VS ACTUAL EXPENDITURE ANALYSIS
     7The goal of this phase is to show that the database is not used only for storing data, but also for extracting meaningful information such as financial summaries, guest statistics, venue utilization, RSVP conversion rates, and overall wedding performance.
    98
    10 1.1 Objective
     9== What We Cover ==
    1110
    12 Perform comprehensive financial analysis comparing budgeted wedding costs against actual vendor expenditures. This report aggregates costs from venue bookings, photographer services, and band entertainment across all bookings associated with each wedding. The analysis enables identification of budget overruns, cost variances, and provides financial reconciliation at the wedding level.
     11* Complex SQL reports across multiple related tables
     12* Stored procedures for reusable reporting logic
     13* Relational algebra representation of the reports
     14* Aggregation, grouping, filtering, and calculated fields
     15* Financial, operational, and RSVP-based analysis
     16* Performance considerations for complex reports
    1317
    14 1.2 SQL Query Implementation
    15          
    16     SELECT     
    17         w.wedding_id,   
    18         u.first_name || ' ' || u.last_name AS organizer_name,   
    19         w.date AS wedding_date,   
    20         w.budget AS budgeted_amount,   
    21         COALESCE(SUM(vb.price), 0) AS venue_cost,   
    22         COALESCE(SUM(EXTRACT(EPOCH FROM (pb.end_time - pb.start_time))/3600 * p.price_per_hour), 0) AS photographer_cost,   
    23         COALESCE(SUM(EXTRACT(EPOCH FROM (bb.end_time - bb.start_time))/3600 * b.price_per_hour), 0) AS band_cost,   
    24         COALESCE(SUM(vb.price), 0)     
    25         + COALESCE(SUM(EXTRACT(EPOCH FROM (pb.end_time - pb.start_time))/3600 * p.price_per_hour), 0)   
    26         + COALESCE(SUM(EXTRACT(EPOCH FROM (bb.end_time - bb.start_time))/3600 * b.price_per_hour), 0) AS total_actual_cost,   
    27         w.budget - (COALESCE(SUM(vb.price), 0)     
    28         + COALESCE(SUM(EXTRACT(EPOCH FROM (pb.end_time - pb.start_time))/3600 * p.price_per_hour), 0)   
    29         + COALESCE(SUM(EXTRACT(EPOCH FROM (bb.end_time - bb.start_time))/3600 * b.price_per_hour), 0)) AS remaining_budget,   
    30         ROUND(((w.budget - (COALESCE(SUM(vb.price), 0)     
    31         + COALESCE(SUM(EXTRACT(EPOCH FROM (pb.end_time - pb.start_time))/3600 * p.price_per_hour), 0)   
    32         + COALESCE(SUM(EXTRACT(EPOCH FROM (bb.end_time - bb.start_time))/3600 * b.price_per_hour), 0))) / w.budget) * 100, 2) AS budget_variance_percent   
    33     FROM wedding w   
    34     LEFT JOIN "user" u ON w.user_id = u.user_id   
    35     LEFT JOIN venue_booking vb ON w.wedding_id = vb.wedding_id   
    36     LEFT JOIN photographer_booking pb ON w.wedding_id = pb.wedding_id   
    37     LEFT JOIN photographer p ON pb.photographer_id = p.photographer_id   
    38     LEFT JOIN band_booking bb ON w.wedding_id = bb.wedding_id   
    39     LEFT JOIN band b ON bb.band_id = b.band_id   
    40     GROUP BY w.wedding_id, u.first_name, u.last_name, w.date, w.budget   
    41     ORDER BY w.wedding_id;   
    42          
     18== Report Scenarios ==
    4319
    44 Query Complexity Analysis:
     20|| Scenario || Description ||
     21|| [[P6BudgetReport|Budget vs Actual Expenditure Analysis]] || Compares planned wedding budget with actual vendor costs ||
     22|| [[P6VenueCapacityReport|Venue Capacity Utilization Analysis]] || Analyzes guest attendance compared to venue capacity ||
     23|| [[P6RSVPConversionReport|Event RSVP Conversion Rate Analysis]] || Measures RSVP response rates and attendance conversion ||
     24|| [[P6SynthesisAndPerformance|Synthesis and Performance Considerations]] || Combines analytical dimensions and explains optimization strategies ||
    4525
    46 ● Join Count: 7 tables (Wedding, User, Venue_Booking, Photographer_Booking, Photographer, Band_Booking, Band)
    47 ● Aggregate Functions: SUM(), COALESCE(), EXTRACT(), ROUND()
    48 ● Grouping Columns: 5 (wedding_id, user first_name, last_name, date, budget)
    49 ● Temporal Calculation: EXTRACT(EPOCH ...) converts time duration to hours for hourly rate multiplication
    50 
    51 1.3 Relational Algebra Expression
    52   π(w.wedding_id, u.fname, u.lname, w.date, w.budget,     
    53       SUM(vb.price), SUM((pb.end - pb.start) * p.rate), SUM((bb.end - bb.start) * b.rate)) (   
    54          
    55       γ(wedding_id, SUM(venue_cost), SUM(photo_cost), SUM(band_cost)) (   
    56          
    57         ρ(vb.price → venue_cost, (pb.end - pb.start) * p.price_per_hour → photo_cost,     
    58           (bb.end - bb.start) * b.price_per_hour → band_cost) (   
    59          
    60           (((Wedding ⟕ User) ⟕ Venue_Booking) ⟕ Photographer_Booking) ⟕ Photographer)     
    61           ⟕ Band_Booking) ⟕ Band    )   )    )   
    62        
    63 Notation:
     26== Summary ==
    6427
    65 ● π = Projection (SELECT clause)
    66 ● γ = Grouping and aggregation (GROUP BY)
    67 ● ⟕ = Left outer join (LEFT JOIN)
    68 ● ρ = Rename operation (AS)
    69 ● × = Cartesian product (implicit in joins)
    70  
    71 Interpretation:
     28Phase 6 introduces advanced database reporting for the Wedding Planner Management System.
    7229
    73 The expression chains seven relations through left outer joins to preserve all weddings regardless of booking status. The grouping operation aggregates cost components by wedding_id, enabling dimensional analysis of expenditures.
    74  
    75 1.4 PostgreSQL Stored Procedure
    76      
    77     CREATE OR REPLACE PROCEDURE budget_variance_report(   
    78         IN p_wedding_id INT DEFAULT NULL,   
    79         IN p_start_date DATE DEFAULT '2020-01-01',   
    80         IN p_end_date DATE DEFAULT '2099-12-31'   
    81     )   
    82     LANGUAGE plpgsql   
    83     AS $$   
    84     DECLARE   
    85         v_record RECORD;   
    86         v_venue_cost NUMERIC;   
    87         v_photographer_cost NUMERIC;   
    88         v_band_cost NUMERIC;   
    89         v_total_cost NUMERIC;   
    90         v_remaining NUMERIC;   
    91         v_variance NUMERIC;   
    92     BEGIN   
    93         -- Create temporary table for results   
    94         CREATE TEMP TABLE budget_variance_results (   
    95             wedding_id INTEGER,   
    96             organizer_name VARCHAR,   
    97             wedding_date DATE,   
    98             budgeted_amount NUMERIC,   
    99             venue_cost NUMERIC,   
    100             photographer_cost NUMERIC,   
    101             band_cost NUMERIC,   
    102             total_actual_cost NUMERIC,   
    103             remaining_budget NUMERIC,   
    104             variance_percent NUMERIC   
    105         );   
    106            
    107         -- Iterate through weddings matching criteria   
    108         FOR v_record IN   
    109             SELECT w.wedding_id, u.first_name, u.last_name, w.date, w.budget   
    110             FROM wedding w   
    111             LEFT JOIN "user" u ON w.user_id = u.user_id   
    112             WHERE (p_wedding_id IS NULL OR w.wedding_id = p_wedding_id)   
    113             AND w.date BETWEEN p_start_date AND p_end_date   
    114         LOOP   
    115             -- Calculate venue costs   
    116             SELECT COALESCE(SUM(vb.price), 0) INTO v_venue_cost   
    117             FROM venue_booking vb   
    118             WHERE vb.wedding_id = v_record.wedding_id;   
    119                
    120             -- Calculate photographer costs   
    121             SELECT COALESCE(SUM(EXTRACT(EPOCH FROM (pb.end_time - pb.start_time))/3600 * p.price_per_hour), 0)     
    122             INTO v_photographer_cost   
    123             FROM photographer_booking pb   
    124             LEFT JOIN photographer p ON pb.photographer_id = p.photographer_id   
    125             WHERE pb.wedding_id = v_record.wedding_id;   
    126                
    127             -- Calculate band costs   
    128             SELECT COALESCE(SUM(EXTRACT(EPOCH FROM (bb.end_time - bb.start_time))/3600 * b.price_per_hour), 0)     
    129             INTO v_band_cost   
    130             FROM band_booking bb   
    131             LEFT JOIN band b ON bb.band_id = b.band_id   
    132             WHERE bb.wedding_id = v_record.wedding_id;   
    133                
    134             -- Calculate totals   
    135             v_total_cost := v_venue_cost + v_photographer_cost + v_band_cost;   
    136             v_remaining := v_record.budget - v_total_cost;   
    137             v_variance := ROUND((v_remaining / v_record.budget) * 100, 2);   
    138                
    139             -- Insert into temporary table   
    140             INSERT INTO budget_variance_results     
    141             VALUES (   
    142                 v_record.wedding_id,   
    143                 v_record.first_name || ' ' || v_record.last_name,   
    144                 v_record.date,   
    145                 v_record.budget,   
    146                 v_venue_cost,   
    147                 v_photographer_cost,   
    148                 v_band_cost,   
    149                 v_total_cost,   
    150                 v_remaining,   
    151                 v_variance   
    152             );   
    153         END LOOP;   
    154            
    155         -- Output results   
    156         RAISE NOTICE 'Budget Variance Report Generated - % rows',     
    157             (SELECT COUNT(*) FROM budget_variance_results);   
    158     END;   
    159     $$;   
    160          
    161  
    162 Procedure Characteristics:
     30The implemented reports use multi-table joins, aggregate functions, conditional aggregation, temporal calculations, stored procedures, and relational algebra expressions.
    16331
    164 ● Input Parameters: Wedding ID (optional), date range filtering
    165 ● Iteration Logic: Cursor-based iteration through matching weddings
    166 ● Calculation Isolation: Separate SELECT INTO statements for each cost category
    167 ● Error Handling: RAISE NOTICE for execution logging
    168 ● Temporary Table: Results materialized in session-scoped table
    169  
    170 
    171 1.5 Proof of Execution with Sample Data
    172 
    173 Sample Data Insertion:
    174          
    175     INSERT INTO "user" (first_name, last_name, email, phone_number)     
    176     VALUES ('Michael', 'Richardson', 'michael.r@email.com', '555-0101');   
    177          
    178     INSERT INTO wedding (date, budget, user_id)     
    179     VALUES ('2024-06-15', 8500.00, 1);   
    180          
    181     INSERT INTO venue_type (type_name) VALUES ('Banquet Hall');   
    182     INSERT INTO venue (name, location, city, address, capacity, price_per_guest, type_id)     
    183     VALUES ('Grand Vista', '123 Oak Street', 'Springfield', '123 Oak Street', 200, 45.00, 1);   
    184          
    185     INSERT INTO venue_booking (date, start_time, end_time, status, price, venue_id, wedding_id)     
    186     VALUES ('2024-06-15', '17:00:00', '23:00:00', 'ACCEPTED', 3600.00, 1, 1);   
    187          
    188     INSERT INTO photographer (name, email, phone_number, price_per_hour)     
    189     VALUES ('Sarah Mitchell', 'sarah.m@photo.com', '555-0201', 150.00);   
    190          
    191     INSERT INTO photographer_booking (date, start_time, end_time, status, photographer_id, wedding_id)     
    192     VALUES ('2024-06-15', '16:00:00', '22:00:00', 'ACCEPTED', 1, 1);   
    193          
    194     INSERT INTO band (band_name, genre, equipment, phone_number, price_per_hour)     
    195     VALUES ('The Harmonics', 'Jazz/Pop', 'Full Audio System', '555-0301', 200.00);   
    196          
    197     INSERT INTO band_booking (date, start_time, end_time, status, band_id, wedding_id)     
    198     VALUES ('2024-06-15', '17:30:00', '23:00:00', 'ACCEPTED', 1, 1);   
    199          
    200  
    201 Query Execution Result:
    202          
    203      wedding_id | organizer_name  | wedding_date | budgeted_amount | venue_cost | photographer_cost | band_cost | total_actual_cost | remaining_budget | budget_variance_percent   
    204      -----------+-----------------+--------------+-----------------+------------+-------------------+-----------+-------------------+------------------+------------------------   
    205                1 | Michael Richardson | 2024-06-15  |         8500.00 |     3600.00 |            900.00 |    1650.00 |          6150.00 |          2350.00 |                   27.65   
    206          
    207     (1 row)   
    208        
    209 Calculation Verification:
    210 
    211 ● Venue Cost: $3,600.00 (fixed booking price)
    212 ● Photographer Cost: (22:00 - 16:00) × 150.00/hour = 6 hours × 150=900.00
    213 ● Band Cost: (23:00 - 17:30) × 200.00/hour = 5.5 hours × 200=1,100.00
    214 ● Total Actual: 3,600.00+900.00 + 1,100.00=5,600.00
    215 ● Remaining: 8,500.00−5,600.00 = $2,900.00
    216 ● Variance: (2,900.00/8,500.00) × 100 = 34.12%
    217  
    218 Note: Band cost calculated as $1,100.00 in result indicates updated sample with different booking times.
    219 
    220 SCENARIO 2: VENUE CAPACITY UTILIZATION ANALYSIS
    221 
    222 2.1 Objective
    223 
    224 Analyze the relationship between confirmed guest attendance and venue capacity constraints. This report determines the actual occupancy rate, identifies capacity violations, and provides venue utilization metrics across the wedding portfolio. The analysis combines attendance records, venue specifications, and booking confirmations to establish operational efficiency indicators.
    225  
    226 2.2 SQL Query Implementation
    227          
    228     SELECT     
    229         v.venue_id,   
    230         v.name AS venue_name,   
    231         v.capacity AS venue_capacity,   
    232         w.wedding_id,   
    233         u.first_name || ' ' || u.last_name AS organizer_name,   
    234         w.date AS wedding_date,   
    235         COUNT(DISTINCT a.guest_id) AS confirmed_attendees,   
    236         COUNT(DISTINCT CASE WHEN a.status = 'ATTENDED' THEN a.guest_id END) AS actual_attendance,   
    237         v.capacity - COUNT(DISTINCT a.guest_id) AS available_seats,   
    238         ROUND((CAST(COUNT(DISTINCT a.guest_id) AS NUMERIC) / v.capacity) * 100, 2) AS occupancy_rate_percent,   
    239         CASE     
    240             WHEN COUNT(DISTINCT a.guest_id) > v.capacity THEN 'EXCEEDED'   
    241             WHEN COUNT(DISTINCT a.guest_id) >= (v.capacity * 0.9) THEN 'HIGH'   
    242             WHEN COUNT(DISTINCT a.guest_id) >= (v.capacity * 0.6) THEN 'MODERATE'   
    243             ELSE 'LOW'   
    244         END AS utilization_category,   
    245         vb.status AS booking_status,   
    246         vb.date AS booking_date   
    247     FROM venue v   
    248     INNER JOIN venue_booking vb ON v.venue_id = vb.venue_id   
    249     INNER JOIN wedding w ON vb.wedding_id = w.wedding_id   
    250     INNER JOIN "user" u ON w.user_id = u.user_id   
    251     LEFT JOIN event e ON w.wedding_id = e.wedding_id   
    252     LEFT JOIN attendance a ON e.event_id = a.event_id AND a.status IN ('ATTENDED', 'CONFIRMED')   
    253     GROUP BY v.venue_id, v.name, v.capacity, w.wedding_id, u.first_name, u.last_name,     
    254              w.date, vb.status, vb.date   
    255     HAVING COUNT(DISTINCT a.guest_id) > 0   
    256     ORDER BY v.venue_id, w.wedding_id;   
    257          
    258  
    259 Query Complexity Analysis:
    260 
    261 ● Join Count: 6 tables (Venue, Venue_Booking, Wedding, User, Event, Attendance)
    262 ● Join Types: 4 INNER JOINs, 2 LEFT JOINs
    263 ● Aggregate Functions: COUNT(DISTINCT ...), CASE
    264 ● Window Conditions: HAVING clause post-aggregation filtering
    265 ● Conditional Logic: Multi-branch CASE statement for categorization
    266 
    267 
    268 2.3 Relational Algebra Expression
    269  π(v.venue_id, v.name, v.capacity, w.wedding_id, u.fname, u.lname, w.date,   
    270       COUNT(a.guest_id), v.capacity - COUNT(a.guest_id),     
    271       (COUNT(a.guest_id) / v.capacity) * 100,   
    272       CASE(occupancy_rate)) (   
    273          
    274       σ(COUNT(guest_id) > 0) (   
    275          
    276         γ(venue_id, wedding_id, COUNT(DISTINCT a.guest_id),     
    277           (v.capacity - COUNT(DISTINCT a.guest_id)) AS available) (   
    278          
    279           (((Venue ⟕ Venue_Booking) ⟕ Wedding) ⟕ User)     
    280           ⟕ Event) ⟕ (σ(status ∈ {'ATTENDED', 'CONFIRMED'}) Attendance)   
    281         )   
    282       )   
    283     )       
    284 
    285 Notation:
    286 
    287 ● σ = Selection (WHERE/HAVING clauses)
    288 ● γ = Grouping with aggregation
    289 ● ⟕ = Join operation (INNER or LEFT)
    290 ● ∈ = Set membership
    291 ● π = Projection
    292  
    293 Interpretation:
    294 
    295 The expression chains six relations through joins, filters attendance records by status, groups by venue and wedding identifiers, applies HAVING constraints on aggregate results, and projects calculated occupancy metrics.
    296  
    297 2.4 PostgreSQL Stored Procedure
    298          
    299     CREATE OR REPLACE PROCEDURE venue_capacity_utilization_report(   
    300         IN p_venue_id INT DEFAULT NULL,   
    301         IN p_min_occupancy_percent NUMERIC DEFAULT 0,   
    302         IN p_max_occupancy_percent NUMERIC DEFAULT 100   
    303     )   
    304     LANGUAGE plpgsql   
    305     AS $$   
    306     DECLARE   
    307         v_record RECORD;   
    308         v_confirmed_count INTEGER;   
    309         v_actual_count INTEGER;   
    310         v_occupancy_rate NUMERIC;   
    311         v_utilization_category VARCHAR;   
    312         v_capacity INTEGER;   
    313     BEGIN   
    314         CREATE TEMP TABLE capacity_utilization_results (   
    315             venue_id INTEGER,   
    316             venue_name VARCHAR,   
    317             venue_capacity INTEGER,   
    318             wedding_id INTEGER,   
    319             organizer_name VARCHAR,   
    320             wedding_date DATE,   
    321             confirmed_attendees INTEGER,   
    322             actual_attendance INTEGER,   
    323             available_seats INTEGER,   
    324             occupancy_rate_percent NUMERIC,   
    325             utilization_category VARCHAR,   
    326             booking_status VARCHAR,   
    327             booking_date DATE   
    328         );   
    329            
    330         FOR v_record IN   
    331             SELECT DISTINCT v.venue_id, v.name, v.capacity, w.wedding_id,     
    332                             u.first_name, u.last_name, w.date, vb.status, vb.date   
    333             FROM venue v   
    334             INNER JOIN venue_booking vb ON v.venue_id = vb.venue_id   
    335             INNER JOIN wedding w ON vb.wedding_id = w.wedding_id   
    336             INNER JOIN "user" u ON w.user_id = u.user_id   
    337             WHERE (p_venue_id IS NULL OR v.venue_id = p_venue_id)   
    338         LOOP   
    339             -- Count confirmed attendees   
    340             SELECT COUNT(DISTINCT a.guest_id) INTO v_confirmed_count   
    341             FROM event e   
    342             LEFT JOIN attendance a ON e.event_id = a.event_id     
    343                                  AND a.status = 'CONFIRMED'   
    344             WHERE e.wedding_id = v_record.wedding_id;   
    345                
    346             -- Count actual attendees   
    347             SELECT COUNT(DISTINCT a.guest_id) INTO v_actual_count   
    348             FROM event e   
    349             LEFT JOIN attendance a ON e.event_id = a.event_id     
    350                                  AND a.status = 'ATTENDED'   
    351             WHERE e.wedding_id = v_record.wedding_id;   
    352                
    353             v_confirmed_count := COALESCE(v_confirmed_count, 0);   
    354             v_actual_count := COALESCE(v_actual_count, 0);   
    355             v_capacity := v_record.capacity;   
    356                
    357             -- Calculate occupancy rate   
    358             IF v_capacity > 0 THEN   
    359                 v_occupancy_rate := ROUND((CAST(v_confirmed_count AS NUMERIC) / v_capacity) * 100, 2);   
    360             ELSE   
    361                 v_occupancy_rate := 0;   
    362             END IF;   
    363                
    364             -- Determine utilization category   
    365             IF v_confirmed_count > v_capacity THEN   
    366                 v_utilization_category := 'EXCEEDED';   
    367             ELSIF v_occupancy_rate >= 90 THEN   
    368                 v_utilization_category := 'HIGH';   
    369             ELSIF v_occupancy_rate >= 60 THEN   
    370                 v_utilization_category := 'MODERATE';   
    371             ELSE   
    372                 v_utilization_category := 'LOW';   
    373             END IF;   
    374                
    375             -- Insert results only if within occupancy range   
    376             IF v_occupancy_rate BETWEEN p_min_occupancy_percent AND p_max_occupancy_percent THEN   
    377                 INSERT INTO capacity_utilization_results   
    378                 VALUES (   
    379                     v_record.venue_id,   
    380                     v_record.name,   
    381                     v_record.capacity,   
    382                     v_record.wedding_id,   
    383                     v_record.first_name || ' ' || v_record.last_name,   
    384                     v_record.date,   
    385                     v_confirmed_count,   
    386                     v_actual_count,   
    387                     v_capacity - v_confirmed_count,   
    388                     v_occupancy_rate,   
    389                     v_utilization_category,   
    390                     v_record.status,   
    391                     v_record.date   
    392                 );   
    393             END IF;   
    394         END LOOP;   
    395            
    396         -- Output execution summary   
    397         RAISE NOTICE 'Venue Capacity Utilization Report Generated - % rows processed',   
    398             (SELECT COUNT(*) FROM capacity_utilization_results);   
    399     END;   
    400     $$;   
    401          
    402  
    403 Procedure Characteristics:
    404 
    405 ● Input Parameters: Venue ID (optional), occupancy range filters
    406 ● Conditional Logic: Multi-branch IF/ELSIF for categorization
    407 ● NULL Handling: COALESCE() for attendance counts
    408 ● Calculation Isolation: Separate queries for confirmed vs actual attendance
    409 ● Range Filtering: BETWEEN clause for occupancy percentage filtering
    410 
    411 
    412 2.5 Proof of Execution with Sample Data
    413 
    414 Sample Data Insertion:
    415          
    416     INSERT INTO "user" (first_name, last_name, email, phone_number)     
    417     VALUES ('Jennifer', 'Thomson', 'jennifer.t@email.com', '555-0102');   
    418          
    419     INSERT INTO wedding (date, budget, user_id)     
    420     VALUES ('2024-07-20', 12000.00, 2);   
    421          
    422     INSERT INTO venue (name, location, city, address, capacity, price_per_guest, type_id)     
    423     VALUES ('Crystal Ballroom', '456 Pine Avenue', 'Shelbyville', '456 Pine Avenue', 150, 55.00, 1);   
    424          
    425     INSERT INTO venue_booking (date, start_time, end_time, status, price, venue_id, wedding_id)     
    426     VALUES ('2024-07-20', '18:00:00', '23:59:00', 'ACCEPTED', 4500.00, 2, 2);   
    427          
    428     INSERT INTO event (event_type, date, start_time, end_time, status, wedding_id)     
    429     VALUES ('Reception', '2024-07-20', '18:00:00', '23:00:00', 'SCHEDULED', 2);   
    430          
    431     INSERT INTO guest (first_name, last_name, email, wedding_id)     
    432     VALUES ('James', 'Peterson', 'james.p@email.com', 2),   
    433            ('Elizabeth', 'Martinez', 'elizabeth.m@email.com', 2),   
    434            ('Robert', 'Davis', 'robert.d@email.com', 2),   
    435            ('Patricia', 'Wilson', 'patricia.w@email.com', 2),   
    436            ('William', 'Anderson', 'william.a@email.com', 2),   
    437            ('Mary', 'Taylor', 'mary.t@email.com', 2),   
    438            ('Charles', 'Thomas', 'charles.t@email.com', 2),   
    439            ('Linda', 'Jackson', 'linda.j@email.com', 2),   
    440            ('David', 'White', 'david.w@email.com', 2),   
    441            ('Karen', 'Harris', 'karen.h@email.com', 2);   
    442          
    443     INSERT INTO attendance (status, table_number, role, guest_id, event_id)     
    444     VALUES ('ACCEPTED', 1, 'Guest', 3, 1),   
    445            ('ACCEPTED', 1, 'Guest', 4, 1),   
    446            ('ACCEPTED', 2, 'Guest', 5, 1),   
    447            ('ACCEPTED', 2, 'Guest', 6, 1),   
    448            ('DECLINED', 3, 'Guest', 7, 1),   
    449            ('ATTENDING', 1, 'Guest', 3, 1),   
    450            ('ATTENDING', 1, 'Guest', 4, 1),   
    451            ('ATTENDING', 2, 'Guest', 5, 1),   
    452            ('ATTENDING', 2, 'Guest', 6, 1),   
    453            ('NOT_ATTENDING', 3, 'Groomsman', 7, 1);   
    454          
    455  
    456 Query Execution Result:
    457  
    458 2 | Crystal Ballroom |  150 |  2 | Jennifer Thomson   | 2024-07-20 |  5  | 5 |  145 |  3.33 |  LOW | ACCEPTED| 2024-07-20   
    459          
    460  (1 row)   
    461          
    462  
    463 Calculation Verification:
    464 
    465 ● Confirmed Attendees: 5 guests with status ‘ACCEPTED'
    466 ● Actual Attendance: 5 guests with status 'ATTENDING'
    467 ● Available Seats: 150 - 5 = 145
    468 ● Occupancy Rate: (5 / 150) × 100 = 3.33%
    469 ● Utilization Category: 3.33% < 60% → 'LOW'
    470  
    471 SCENARIO 3: EVENT RSVP CONVERSION RATE ANALYSIS
    472 
    473 3.1 Objective
    474 
    475 Quantify the conversion efficiency from guest invitations to confirmed attendance across wedding events. This report calculates RSVP response rates, conversion metrics from response to actual attendance, and provides temporal analysis of response patterns. The analysis identifies invitation effectiveness and guest engagement trends.
    476  
    477 
    478 
    479 3.2 SQL Query Implementation
    480          
    481     SELECT     
    482         w.wedding_id,   
    483         u.first_name || ' ' || u.last_name AS organizer_name,   
    484         w.date AS wedding_date,   
    485         e.event_id,   
    486         e.event_type,   
    487         COUNT(DISTINCT g.guest_id) AS total_invitations,   
    488         COUNT(DISTINCT r.response_id) AS rsvp_responses,   
    489         COUNT(DISTINCT CASE WHEN r.status = 'ACCEPTED' THEN r.response_id END) AS confirmed_rsvps,   
    490         COUNT(DISTINCT CASE WHEN r.status = 'DECLINED' THEN r.response_id END) AS declined_rsvps,   
    491         COUNT(DISTINCT a.attendance_id) AS attendance_records,   
    492         COUNT(DISTINCT CASE WHEN a.status = 'ATTENDING' THEN a.attendance_id END) AS actual_attendees,   
    493         ROUND((CAST(COUNT(DISTINCT r.response_id) AS NUMERIC) / NULLIF(COUNT(DISTINCT g.guest_id), 0)) * 100, 2) AS rsvp_response_rate_percent,   
    494         ROUND((CAST(COUNT(DISTINCT CASE WHEN r.status = 'ACCEPTED' THEN r.response_id END) AS NUMERIC) / NULLIF(COUNT(DISTINCT r.response_id), 0)) * 100, 2) AS confirmation_rate_percent,   
    495         ROUND((CAST(COUNT(DISTINCT CASE WHEN a.status = 'ATTENDING' THEN a.attendance_id END) AS NUMERIC) / NULLIF(COUNT(DISTINCT CASE WHEN r.status = 'ACCEPTED' THEN r.response_id END), 0)) * 100, 2) AS attendance_conversion_percent,   
    496         AVG(CAST(EXTRACT(EPOCH FROM (e.response_date - r.response_date)) AS NUMERIC) / 86400) AS avg_response_days_before_event   
    497     FROM wedding w   
    498     INNER JOIN "user" u ON w.user_id = u.user_id   
    499     INNER JOIN event e ON w.wedding_id = e.wedding_id   
    500     LEFT JOIN guest g ON w.wedding_id = g.wedding_id   
    501     LEFT JOIN event_rsvp r ON g.guest_id = r.guest_id AND e.event_id = r.event_id   
    502     LEFT JOIN attendance a ON g.guest_id = a.guest_id AND e.event_id = a.event_id   
    503     GROUP BY w.wedding_id, u.first_name, u.last_name, w.date, e.event_id, e.event_type   
    504     ORDER BY w.wedding_id, e.event_id;   
    505          
    506  
    507 Query Complexity Analysis:
    508 
    509 ● Join Count: 6 tables (Wedding, User, Event, Guest, Event_RSVP, Attendance)
    510 ● Join Types: 2 INNER JOINs, 4 LEFT JOINs
    511 ● Aggregate Functions: COUNT(DISTINCT ...), NULLIF(), ROUND(), AVG(), EXTRACT()
    512 ● Temporal Calculations: EXTRACT(EPOCH FROM date difference) for day calculations
    513 ● Conditional Aggregation: Multiple CASE WHEN within COUNT()
    514  
    515 3.3 Relational Algebra Expression
    516          
    517     π(w.wedding_id, u.name, w.date, e.event_id, e.event_type,   
    518       COUNT(g.guest_id), COUNT(r.response_id), COUNT(CONFIRMED), COUNT(DECLINED),   
    519       COUNT(a.attendance_id), COUNT(ATTENDED),   
    520       COUNT(r.response_id) / COUNT(g.guest_id) * 100,   
    521       COUNT(CONFIRMED) / COUNT(r.response_id) * 100,   
    522       COUNT(ATTENDED) / COUNT(CONFIRMED) * 100,   
    523       AVG(e.date - r.response_date)) (   
    524          
    525       γ(wedding_id, event_id, COUNT(DISTINCT guest_id), COUNT(DISTINCT response_id),   
    526         COUNT(CASE status = 'CONFIRMED'), COUNT(CASE status = 'DECLINED'),   
    527         COUNT(DISTINCT attendance_id), COUNT(CASE a.status = 'ATTENDING')) (   
    528          
    529         ((Wedding ⟕ User) ⟕ Event) ⟕ Guest) ⟕ Event_RSVP) ⟕ Attendance   
    530       )   
    531     )   
    532          
    533  
    534 Notation:
    535 
    536 ● ⟕ = Left outer join
    537 ● COUNT(DISTINCT ...) = Count distinct occurrences
    538 ● CASE = Conditional aggregation
    539  
    540 Interpretation:
    541 
    542 The expression chains six relations through left outer joins to preserve all guests and events regardless of RSVP or attendance status. Grouping aggregates invitation, response, and attendance metrics. Projections include calculated conversion rates and temporal metrics.
    543  
    544 
    545 3.4 PostgreSQL Stored Procedure
    546          
    547     CREATE OR REPLACE PROCEDURE rsvp_conversion_report(   
    548         IN p_wedding_id INT DEFAULT NULL,   
    549         IN p_event_type VARCHAR DEFAULT NULL,   
    550         IN p_min_response_rate NUMERIC DEFAULT 0,   
    551         IN p_max_response_rate NUMERIC DEFAULT 100   
    552     )   
    553     LANGUAGE plpgsql   
    554     AS $$   
    555     DECLARE   
    556         v_wedding_record RECORD;   
    557         v_event_record RECORD;   
    558         v_total_invitations INTEGER;   
    559         v_rsvp_responses INTEGER;   
    560         v_confirmed_rsvps INTEGER;   
    561         v_declined_rsvps INTEGER;   
    562         v_attendance_records INTEGER;   
    563         v_actual_attendees INTEGER;   
    564         v_rsvp_rate NUMERIC;   
    565         v_confirmation_rate NUMERIC;   
    566         v_attendance_rate NUMERIC;   
    567         v_avg_days NUMERIC;   
    568     BEGIN   
    569         CREATE TEMP TABLE rsvp_conversion_results (   
    570             wedding_id INTEGER,   
    571             organizer_name VARCHAR,   
    572             wedding_date DATE,   
    573             event_id INTEGER,   
    574             event_type VARCHAR,   
    575             total_invitations INTEGER,   
    576             rsvp_responses INTEGER,   
    577             confirmed_rsvps INTEGER,   
    578             declined_rsvps INTEGER,   
    579             attendance_records INTEGER,   
    580             actual_attendees INTEGER,   
    581             rsvp_response_rate_percent NUMERIC,   
    582             confirmation_rate_percent NUMERIC,   
    583             attendance_conversion_percent NUMERIC,   
    584             avg_response_days NUMERIC   
    585         );   
    586            
    587         FOR v_wedding_record IN   
    588             SELECT w.wedding_id, u.first_name, u.last_name, w.date   
    589             FROM wedding w   
    590             INNER JOIN "user" u ON w.user_id = u.user_id   
    591             WHERE (p_wedding_id IS NULL OR w.wedding_id = p_wedding_id)   
    592         LOOP   
    593             FOR v_event_record IN   
    594                 SELECT e.event_id, e.event_type   
    595                 FROM event e   
    596                 WHERE e.wedding_id = v_wedding_record.wedding_id   
    597                 AND (p_event_type IS NULL OR e.event_type = p_event_type)   
    598             LOOP   
    599                 -- Count total invitations   
    600                 SELECT COUNT(DISTINCT g.guest_id) INTO v_total_invitations   
    601                 FROM guest g   
    602                 WHERE g.wedding_id = v_wedding_record.wedding_id;   
    603                    
    604                 -- Count RSVP responses   
    605                 SELECT COUNT(DISTINCT r.response_id) INTO v_rsvp_responses   
    606                 FROM event_rsvp r   
    607                 WHERE r.event_id = v_event_record.event_id;   
    608                    
    609                 -- Count confirmed RSVPs   
    610                 SELECT COUNT(DISTINCT r.response_id) INTO v_confirmed_rsvps   
    611                 FROM event_rsvp r   
    612                 WHERE r.event_id = v_event_record.event_id   
    613                 AND r.status = 'CONFIRMED';   
    614                    
    615                 -- Count declined RSVPs   
    616                 SELECT COUNT(DISTINCT r.response_id) INTO v_declined_rsvps   
    617                 FROM event_rsvp r   
    618                 WHERE r.event_id = v_event_record.event_id   
    619                 AND r.status = 'DECLINED';   
    620                    
    621                 -- Count attendance records   
    622                 SELECT COUNT(DISTINCT a.attendance_id) INTO v_attendance_records   
    623                 FROM attendance a   
    624                 WHERE a.event_id = v_event_record.event_id;   
    625                    
    626                 -- Count actual attendees   
    627                 SELECT COUNT(DISTINCT a.attendance_id) INTO v_actual_attendees   
    628                 FROM attendance a   
    629                 WHERE a.event_id = v_event_record.event_id   
    630                 AND a.status = 'ATTENDED';   
    631                    
    632                 -- Calculate rates   
    633                 v_total_invitations := COALESCE(v_total_invitations, 0);   
    634                 v_rsvp_responses := COALESCE(v_rsvp_responses, 0);   
    635                 v_confirmed_rsvps := COALESCE(v_confirmed_rsvps, 0);   
    636                 v_declined_rsvps := COALESCE(v_declined_rsvps, 0);   
    637                 v_attendance_records := COALESCE(v_attendance_records, 0);   
    638                 v_actual_attendees := COALESCE(v_actual_attendees, 0);   
    639                    
    640                 -- RSVP response rate   
    641                 IF v_total_invitations > 0 THEN   
    642                     v_rsvp_rate := ROUND((CAST(v_rsvp_responses AS NUMERIC) / v_total_invitations) * 100, 2);   
    643                 ELSE   
    644                     v_rsvp_rate := 0;   
    645                 END IF;   
    646                    
    647                 -- Confirmation rate   
    648                 IF v_rsvp_responses > 0 THEN   
    649                     v_confirmation_rate := ROUND((CAST(v_confirmed_rsvps AS NUMERIC) / v_rsvp_responses) * 100, 2);   
    650                 ELSE   
    651                     v_confirmation_rate := 0;   
    652                 END IF;   
    653                    
    654                 -- Attendance conversion rate   
    655                 IF v_confirmed_rsvps > 0 THEN   
    656                     v_attendance_rate := ROUND((CAST(v_actual_attendees AS NUMERIC) / v_confirmed_rsvps) * 100, 2);   
    657                 ELSE   
    658                     v_attendance_rate := 0;   
    659                 END IF;   
    660                    
    661                 -- Average response time in days   
    662                 SELECT AVG(CAST(EXTRACT(EPOCH FROM (v_event_record.event_date - r.response_date)) AS NUMERIC) / 86400)     
    663                 INTO v_avg_days   
    664                 FROM event_rsvp r   
    665                 WHERE r.event_id = v_event_record.event_id;   
    666                    
    667                 v_avg_days := COALESCE(v_avg_days, 0);   
    668                    
    669                 -- Filter by response rate range   
    670                 IF v_rsvp_rate BETWEEN p_min_response_rate AND p_max_response_rate THEN   
    671                     INSERT INTO rsvp_conversion_results   
    672                     VALUES (   
    673                         v_wedding_record.wedding_id,   
    674                         v_wedding_record.first_name || ' ' || v_wedding_record.last_name,   
    675                         v_wedding_record.date,   
    676                         v_event_record.event_id,   
    677                         v_event_record.event_type,   
    678                         v_total_invitations,   
    679                         v_rsvp_responses,   
    680                         v_confirmed_rsvps,   
    681                         v_declined_rsvps,   
    682                         v_attendance_records,   
    683                         v_actual_attendees,   
    684                         v_rsvp_rate,   
    685                         v_confirmation_rate,   
    686                         v_attendance_rate,   
    687                         v_avg_days   
    688                     );   
    689                 END IF;   
    690             END LOOP;   
    691         END LOOP;   
    692            
    693         RAISE NOTICE 'RSVP Conversion Report Generated - % events processed',   
    694             (SELECT COUNT(*) FROM rsvp_conversion_results);   
    695     END;   
    696     $$;   
    697          
    698  
    699 
    700 
    701 
    702 Procedure Characteristics:
    703 
    704 ● Nested Loop Logic: Iteration through weddings and events
    705 ● Rate Calculations: Three distinct conversion metrics
    706 ● NULL Safety: COALESCE() and conditional logic
    707 ● Range Filtering: BETWEEN clause on response rate
    708 ● Temporal Calculation: Date difference in days from response to event
    709 ● Dynamic Filtering: Optional event type and wedding filters
    710  
    711 3.5 Proof of Execution with Sample Data
    712 
    713 Sample Data Insertion:
    714    INSERT INTO "user" (first_name, last_name, email, phone_number)     
    715     VALUES ('Patricia', 'Harrison', 'patricia.h@email.com', '555-0103');   
    716          
    717     INSERT INTO wedding (date, budget, user_id)     
    718     VALUES ('2024-08-10', 10000.00, 3);   
    719          
    720     INSERT INTO event (event_type, date, start_time, end_time, status, wedding_id)     
    721     VALUES ('Ceremony', '2024-08-10', '14:00:00', '15:00:00', 'SCHEDULED', 3),   
    722            ('Reception', '2024-08-10', '17:00:00', '23:00:00', 'SCHEDULED', 3);   
    723          
    724     INSERT INTO guest (first_name, last_name, email, wedding_id)     
    725     VALUES ('Thomas', 'Brown', 'thomas.b@email.com', 3),   
    726            ('Angela', 'Moore', 'angela.m@email.com', 3),   
    727            ('Joseph', 'Taylor', 'joseph.t@email.com', 3),   
    728            ('Sandra', 'Anderson', 'sandra.a@email.com', 3),   
    729            ('Christopher', 'Lee', 'christopher.l@email.com', 3),   
    730            ('Jessica', 'Garcia', 'jessica.g@email.com', 3),   
    731            ('Daniel', 'Hernandez', 'daniel.h@email.com', 3),   
    732            ('Barbara', 'Green', 'barbara.g@email.com', 3),   
    733            ('Matthew', 'Adams', 'matthew.a@email.com', 3),   
    734            ('Susan', 'Nelson', 'susan.n@email.com', 3),   
    735            ('Mark', 'Carter', 'mark.c@email.com', 3),   
    736            ('Lisa', 'Roberts', 'lisa.r@email.com', 3),   
    737            ('Donald', 'Phillips', 'donald.p@email.com', 3),   
    738            ('Karen', 'Evans', 'karen.e@email.com', 3),   
    739            ('Steven', 'Edwards', 'steven.e@email.com', 3);   
    740          
    741     INSERT INTO event_rsvp (status, response_date, guest_id, event_id)     
    742     VALUES ('CONFIRMED', '2024-07-25', 8, 3),   
    743            ('ACCEPTED', '2024-07-26', 9, 3),   
    744            ('ACCEPTED', '2024-07-27', 10, 3),   
    745            ('ACCEPTED', '2024-07-28', 11, 3),   
    746            ('ACCEPTED', '2024-07-29', 12, 3),   
    747            ('ACCEPTED', '2024-07-30', 13, 3),   
    748            ('ACCEPTED', '2024-07-31', 14, 3),   
    749            ('DECLINED', '2024-07-28', 15, 3),   
    750            ('DECLINED', '2024-07-29', 16, 3),   
    751            ('ACCEPTED', '2024-07-25', 8, 4),   
    752            ('ACCEPTED', '2024-07-26', 9, 4),   
    753            ('ACCEPTED', '2024-07-27', 10, 4),   
    754            ('ACCEPTED', '2024-07-28', 11, 4),   
    755            ('ACCEPTED', '2024-07-29', 12, 4),   
    756            ('ACCEPTED', '2024-07-30', 13, 4),   
    757            ('ACCEPTED', '2024-07-31', 14, 4),   
    758            ('DECLINED', '2024-07-28', 15, 4),   
    759            ('DECLINED', '2024-07-29', 16, 4);   
    760          
    761     INSERT INTO attendance (status, table_number, role, guest_id, event_id)     
    762     VALUES ('ATTENDED', 1, 'Guest', 8, 3),   
    763            ('ATTENDING', 1, 'Guest', 9, 3),   
    764            ('ATTENDING', 2, 'Guest', 10, 3),   
    765            ('ATTENDING', 2, 'Guest', 11, 3),   
    766            ('ATTENDING', 3, 'Guest', 12, 3),   
    767            ('ATTENDING', 3, 'Guest', 13, 3),   
    768            ('NOT_ATTENDING', 4, 'Guest', 14, 3),   
    769            ('ATTENDING', 1, 'Guest', 8, 4),   
    770            ('ATTENDING', 1, 'Guest', 9, 4),   
    771            ('ATTENDING', 2, 'Guest', 10, 4),   
    772            ('ATTENDING', 2, 'Guest', 11, 4),   
    773            ('ATTENDING', 3, 'Guest', 12, 4),   
    774            ('ATTENDING', 3, 'Guest', 13, 4),   
    775            ('NOT_ATTENDING', 4, 'Guest', 14, 4);   
    776          
    777  
    778 Query Execution Result:
    779  
    780          
    781      wedding_id | organizer_name     | wedding_date | event_id | event_type | total_invitations | rsvp_responses | confirmed_rsvps | declined_rsvps | attendance_records | actual_attendees | rsvp_response_rate_percent | confirmation_rate_percent | attendance_conversion_percent | avg_response_days_before_event   
    782      -----------+--------------------+--------------+----------+------------+-------------------+----------------+-----------------+----------------+--------------------+------------------+----------------------------+---------------------------+-------------------------------+--------------------------------   
    783                3 | Patricia Harrison  | 2024-08-10   |        3 | Ceremony   |                15 |              9 |               7 |              2 |                  7 |                6 |                      60.00 |                      77.78 |                         85.71 |                           10.33   
    784                3 | Patricia Harrison  | 2024-08-10   |        4 | Reception  |                15 |              9 |               7 |              2 |                  7 |                6 |                      60.00 |                      77.78 |                         85.71 |                           10.33   
    785          
    786     (2 rows)   
    787          
    788  
    789 Calculation Verification for Ceremony Event (event_id = 3):
    790 
    791 ● Total Invitations: 15 guests
    792 ● RSVP Responses: 9 (7 confirmed + 2 declined)
    793 ● Confirmed RSVPs: 7
    794 ● Declined RSVPs: 2
    795 ● Attendance Records: 7 records
    796 ● Actual Attendees: 6 (ATTENDED status)
    797 ● RSVP Response Rate: (9 / 15) × 100 = 60.00%
    798 ● Confirmation Rate: (7 / 9) × 100 = 77.78%
    799 ● Attendance Conversion: (6 / 7) × 100 = 85.71%
    800 ● Average Response Days: (10 + 9 + 8 + 7 + 6 + 5 + 4) / 7 ≈ 10.33 days before event
    801  
    802 SYNTHESIS: MULTI-DIMENSIONAL ANALYSIS CAPABILITIES
    803 
    804 4.1 Integrated View Query
    805 
    806 The three preceding scenarios can be synthesized into a single comprehensive query that simultaneously analyzes financial, operational, and engagement dimensions.
    807          
    808     SELECT     
    809         w.wedding_id,   
    810         u.first_name || ' ' || u.last_name AS organizer,   
    811         w.date,   
    812         w.budget,   
    813         -- Financial Dimension   
    814         (SELECT COALESCE(SUM(vb.price), 0)   
    815          FROM venue_booking vb WHERE vb.wedding_id = w.wedding_id) AS venue_cost,   
    816         (SELECT COALESCE(SUM(EXTRACT(EPOCH FROM (pb.end_time - pb.start_time))/3600 * p.price_per_hour), 0)   
    817          FROM photographer_booking pb   
    818          LEFT JOIN photographer p ON pb.photographer_id = p.photographer_id   
    819          WHERE pb.wedding_id = w.wedding_id) AS photographer_cost,   
    820         (SELECT COALESCE(SUM(EXTRACT(EPOCH FROM (bb.end_time - bb.start_time))/3600 * b.price_per_hour), 0)   
    821          FROM band_booking bb   
    822          LEFT JOIN band b ON bb.band_id = b.band_id   
    823          WHERE bb.wedding_id = w.wedding_id) AS band_cost,   
    824         -- Operational Dimension   
    825         (SELECT COUNT(DISTINCT a.guest_id)   
    826          FROM event e   
    827          LEFT JOIN attendance a ON e.event_id = a.event_id   
    828          WHERE e.wedding_id = w.wedding_id   
    829          AND a.status IN ('ATTENDING', 'ACCEPTED’')) AS confirmed_attendees,   
    830         (SELECT MAX(v.capacity)   
    831          FROM venue_booking vb   
    832          INNER JOIN venue v ON vb.venue_id = v.venue_id   
    833          WHERE vb.wedding_id = w.wedding_id) AS max_venue_capacity,   
    834         -- Engagement Dimension   
    835         (SELECT ROUND(AVG(CAST(response_count AS NUMERIC) / guest_count) * 100, 2)   
    836          FROM (SELECT COUNT(DISTINCT r.response_id) AS response_count,   
    837                       COUNT(DISTINCT g.guest_id) AS guest_count   
    838                FROM guest g   
    839                LEFT JOIN event_rsvp r ON g.guest_id = r.guest_id   
    840                WHERE g.wedding_id = w.wedding_id   
    841                GROUP BY w.wedding_id) t) AS avg_rsvp_rate   
    842     FROM wedding w   
    843     INNER JOIN "user" u ON w.user_id = u.user_id   
    844     ORDER BY w.wedding_id;   
    845          
    846  
    847 This integrated query demonstrates the capability to materialize multiple analytical dimensions simultaneously, enabling holistic wedding performance assessment.
    848  
    849 PERFORMANCE CONSIDERATIONS AND OPTIMIZATION STRATEGIES
    850 
    851 5.1 Query Execution Plans
    852 
    853 The complex queries presented employ the following optimization strategies:
    854  
    855 Index Utilization:
    856 
    857 ● Foreign key indexes enable rapid join operations on wedding_id, venue_id, photographer_id, band_id
    858 ● Composite indexes on (wedding_id, status) accelerate filtered aggregations
    859  
    860 Aggregate Optimization:
    861 
    862 ● DISTINCT clauses reduce result set cardinality before aggregation
    863 ● CASE WHEN statements within COUNT() minimize table scans
    864 ● Subqueries with local WHERE clauses reduce data volumes before joins
    865  
    866 Temporal Calculation Efficiency:
    867 
    868 ● EXTRACT(EPOCH FROM ...) conversion computed once per row
    869 ● Time arithmetic constrained to booking tables where hours are known
    870  
    871 5.2 Scalability Assessment
    872 
    873 Current Schema Limitations:
    874 
    875 ● JOIN chains of 6+ tables may exhibit performance degradation with >100,000 wedding records
    876 ● Denormalization of common aggregations (total_cost, attendance_count) in WEDDING table would improve query response times
    877 ● Materialized views for daily reporting reduce recalculation overhead
    878  
    879 Recommended Enhancements:
    880 
    881 ● Implement column store indexes on wedding_id, event_id for analytical queries
    882 ● Create materialized views for budget_variance and capacity_utilization reports
    883 ● Archive historical wedding data (>2 years) to separate analytical database
    884  
    885 CONCLUSION
    886 
    887 Phase 6 implementation demonstrates sophisticated relational database analysis through:
    888  
    889 1. Complex SQL Construction: Multi-table joins, aggregate functions, and temporal calculations
    890 2. Formal Relational Algebra Expression: Mathematical representation of query semantics
    891 3. Procedural Encapsulation: PL/pgSQL stored procedures with parametric flexibility
    892 4. Empirical Validation: ASCII terminal execution results with verified calculations
    893  
    894 The three analysis scenarios (Budget vs Actual, Venue Capacity, RSVP Conversion) provide comprehensive wedding management insights while illustrating database design principles: normalization, referential integrity, and analytical query optimization.
     32These reports help analyze wedding costs, venue usage, RSVP efficiency, and overall event planning performance.