diff --git a/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_insert_all_daily_spacy_occupancy_duration.sql b/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_insert_all_daily_spacy_occupancy_duration.sql index 9c3315f..6f74727 100644 --- a/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_insert_all_daily_spacy_occupancy_duration.sql +++ b/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_insert_all_daily_spacy_occupancy_duration.sql @@ -109,7 +109,8 @@ select space_id, FROM final_data ON CONFLICT (space_uuid, event_date) DO UPDATE SET - occupancy_percentage = EXCLUDED.occupancy_percentage; + occupancy_percentage = EXCLUDED.occupancy_percentage, + occupied_seconds = EXCLUDED.occupied_seconds; \ No newline at end of file diff --git a/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_update_daily_space_occupancy_duration.sql b/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_update_daily_space_occupancy_duration.sql index d3c1e88..9ab5de7 100644 --- a/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_update_daily_space_occupancy_duration.sql +++ b/libs/common/src/sql/procedures/fact_daily_space_occupancy_duration/procedure_update_daily_space_occupancy_duration.sql @@ -18,10 +18,9 @@ WITH params AS ( ON p.uuid = d.product_device_uuid WHERE p.cat_name = 'hps' AND l.code = 'presence_state' -), +) --- Step 2: Identify periods when device reports "none" -device_none_periods AS ( +, device_none_periods AS ( SELECT space_id, device_id, @@ -29,20 +28,18 @@ device_none_periods AS ( LEAD(event_time) OVER (PARTITION BY device_id ORDER BY event_time) AS empty_until FROM start_date WHERE value = 'none' -), +) --- Step 3: Clip the "none" periods to the edges of each day -clipped_device_none_periods AS ( +, clipped_device_none_periods AS ( SELECT space_id, GREATEST(empty_from, DATE_TRUNC('day', empty_from)) AS clipped_from, LEAST(empty_until, DATE_TRUNC('day', empty_until) + INTERVAL '1 day') AS clipped_until FROM device_none_periods WHERE empty_until IS NOT NULL -), +) --- Step 4: Break multi-day periods into daily intervals -generated_daily_intervals AS ( +, generated_daily_intervals AS ( SELECT space_id, gs::date AS day, @@ -50,10 +47,9 @@ generated_daily_intervals AS ( LEAST(clipped_until, gs + INTERVAL '1 day') AS interval_end FROM clipped_device_none_periods, LATERAL generate_series(DATE_TRUNC('day', clipped_from), DATE_TRUNC('day', clipped_until), INTERVAL '1 day') AS gs -), +) --- Step 5: Merge overlapping or adjacent intervals per day -merged_intervals AS ( +, merged_intervals AS ( SELECT space_id, day, @@ -69,20 +65,18 @@ merged_intervals AS ( FROM generated_daily_intervals ) sub WHERE prev_end IS NULL OR interval_start > prev_end -), +) --- Step 6: Sum up total missing seconds (device reported "none") per day -missing_seconds_per_day AS ( +, missing_seconds_per_day AS ( SELECT space_id, day AS missing_date, SUM(EXTRACT(EPOCH FROM (interval_end - interval_start))) AS total_missing_seconds FROM merged_intervals GROUP BY space_id, day -), +) --- Step 7: Calculate total occupied time per day (86400 - missing) -occupied_seconds_per_day AS ( +, occupied_seconds_per_day AS ( SELECT space_id, missing_date as event_date, @@ -91,27 +85,32 @@ occupied_seconds_per_day AS ( FROM missing_seconds_per_day ) --- Final Output , final_data as ( -SELECT occupied_seconds_per_day.space_id, - occupied_seconds_per_day.event_date, - occupied_seconds_per_day.occupancy_percentage -FROM occupied_seconds_per_day -join params p on true - and p.space_id = occupied_seconds_per_day.space_id - and p.event_date = occupied_seconds_per_day.event_date -ORDER BY 1,2 + SELECT + occupied_seconds_per_day.space_id, + occupied_seconds_per_day.event_date, + total_occupied_seconds, + occupancy_percentage + FROM occupied_seconds_per_day + JOIN params p + ON p.space_id = occupied_seconds_per_day.space_id + AND p.event_date = occupied_seconds_per_day.event_date ) + INSERT INTO public."space-daily-occupancy-duration" ( space_uuid, event_date, + occupied_seconds, occupancy_percentage ) -select space_id, - event_date, - occupancy_percentage +SELECT + space_id, + event_date, + total_occupied_seconds, + occupancy_percentage FROM final_data ON CONFLICT (space_uuid, event_date) DO UPDATE SET - occupancy_percentage = EXCLUDED.occupancy_percentage; + occupied_seconds = EXCLUDED.occupied_seconds, + occupancy_percentage = EXCLUDED.occupancy_percentage;