From 078de317e4e8e0c4316bf0ba6779d9ceef2a5390 Mon Sep 17 00:00:00 2001 From: Dona Maria Absi <49731027+DonaAbsi@users.noreply.github.com> Date: Wed, 7 May 2025 14:30:56 +0300 Subject: [PATCH] procedures --- .../procedure_fact_daily_space_occupancy.sql | 48 -------- ...dure_insert_fact_daily_space_occupancy.sql | 115 ++++++++++++++++++ ...dure_select_fact_daily_space_occupancy.sql | 19 +++ 3 files changed, 134 insertions(+), 48 deletions(-) delete mode 100644 libs/common/src/sql/procedures/fact_space_occupancy/procedure_fact_daily_space_occupancy.sql create mode 100644 libs/common/src/sql/procedures/fact_space_occupancy/procedure_insert_fact_daily_space_occupancy.sql create mode 100644 libs/common/src/sql/procedures/fact_space_occupancy/procedure_select_fact_daily_space_occupancy.sql diff --git a/libs/common/src/sql/procedures/fact_space_occupancy/procedure_fact_daily_space_occupancy.sql b/libs/common/src/sql/procedures/fact_space_occupancy/procedure_fact_daily_space_occupancy.sql deleted file mode 100644 index c1160bc..0000000 --- a/libs/common/src/sql/procedures/fact_space_occupancy/procedure_fact_daily_space_occupancy.sql +++ /dev/null @@ -1,48 +0,0 @@ --- will return the presence metrics for the days of the selected month -WITH params AS ( - SELECT - TO_DATE(NULLIF($2, ''), 'YYYY-MM') AS month, - string_to_array(NULLIF($4, ''), ',') AS device_ids -) - -, final_data AS ( - SELECT - A.device_uuid, - A.event_date, - A.count_motion_detected, - A.count_presence_detected, - A.count_total_presence_detected - FROM public."presence-sensor-daily-detection" AS A - JOIN params P ON TRUE - WHERE A.device_uuid::text = ANY(P.device_ids) - AND (- - P.month IS NULL - OR date_trunc('month', A.event_date) = P.month - ) -) - -INSERT INTO public."presence-sensor-daily-detection" ( - device_uuid, - event_date, - count_motion_detected, - count_presence_detected, - count_total_presence_detected -) -SELECT - device_uuid, - event_date, - count_motion_detected, - count_presence_detected, - count_total_presence_detected -FROM final_data -ON CONFLICT (device_uuid, event_date) DO UPDATE -SET - count_motion_detected = EXCLUDED.count_motion_detected, - count_presence_detected = EXCLUDED.count_presence_detected, - count_total_presence_detected = EXCLUDED.count_total_presence_detected -WHERE - public."presence-sensor-daily-detection".count_motion_detected IS DISTINCT FROM EXCLUDED.count_motion_detected - OR public."presence-sensor-daily-detection".count_presence_detected IS DISTINCT FROM EXCLUDED.count_presence_detected - OR public."presence-sensor-daily-detection".count_total_presence_detected IS DISTINCT FROM EXCLUDED.count_total_presence_detected; - - diff --git a/libs/common/src/sql/procedures/fact_space_occupancy/procedure_insert_fact_daily_space_occupancy.sql b/libs/common/src/sql/procedures/fact_space_occupancy/procedure_insert_fact_daily_space_occupancy.sql new file mode 100644 index 0000000..84e4dab --- /dev/null +++ b/libs/common/src/sql/procedures/fact_space_occupancy/procedure_insert_fact_daily_space_occupancy.sql @@ -0,0 +1,115 @@ +-- will return the presence metrics for the days of the selected month +WITH params AS ( + SELECT + TO_DATE(NULLIF($2, ''), 'YYYY-MM') AS month, + string_to_array(NULLIF($4, ''), ',') AS device_ids +), + +device_logs AS ( + SELECT + device.uuid AS device_id, + device.created_at, + device.device_tuya_uuid, + device.space_device_uuid AS space_id, + "device-status-log".event_id, + "device-status-log".event_time::timestamp, + "device-status-log".code, + "device-status-log".value, + "device-status-log".log, + LAG("device-status-log".event_time::timestamp) + OVER (PARTITION BY device.uuid + ORDER BY "device-status-log".event_time) AS prev_timestamp, + LAG("device-status-log".value) + OVER (PARTITION BY device.uuid + ORDER BY "device-status-log".event_time) AS prev_value + FROM device + LEFT JOIN "device-status-log" + ON device.uuid = "device-status-log".device_id + LEFT JOIN product + ON product.uuid = device.product_device_uuid + JOIN params P ON TRUE + WHERE product.cat_name = 'hps' + AND "device-status-log".code = 'presence_state' + AND device.uuid::text = ANY(P.device_ids) + AND (P.month IS NULL OR date_trunc('month', "device-status-log".event_time) = P.month) +), + +presence_detection AS ( + SELECT *, + CASE + WHEN value = 'motion' AND prev_value = 'none' THEN 1 ELSE 0 + END AS motion_detected, + CASE + WHEN value = 'presence' AND prev_value = 'none' THEN 1 ELSE 0 + END AS presence_detected + FROM device_logs +), + +presence_detection_summary AS ( + SELECT + pd.device_id, + d.subspace_id, + pd.space_id, + pd.event_time::date AS event_date, + EXTRACT(HOUR FROM pd.event_time)::int AS event_hour, + SUM(motion_detected) AS count_motion_detected, + SUM(presence_detected) AS count_presence_detected, + SUM(motion_detected + presence_detected) AS count_total_presence_detected + FROM presence_detection pd + LEFT JOIN device d ON d.uuid = pd.device_id + GROUP BY 1, 2, 3, 4, 5 +), + +all_dates_and_hours AS ( + SELECT device_id, subspace_id, space_id, event_date, event_hour + FROM ( + SELECT DISTINCT device_id, subspace_id, space_id, event_date + FROM presence_detection_summary + ) d + CROSS JOIN generate_series(0, 23) AS event_hour +), + +table_final AS ( + SELECT + adah.device_id, + adah.event_date, + COALESCE(pds.count_motion_detected, 0) AS count_motion_detected, + COALESCE(pds.count_presence_detected, 0) AS count_presence_detected, + COALESCE(pds.count_total_presence_detected, 0) AS count_total_presence_detected + FROM all_dates_and_hours adah + LEFT JOIN presence_detection_summary pds + ON pds.device_id = adah.device_id + AND pds.event_date = adah.event_date + AND pds.event_hour = adah.event_hour +), + +daily_aggregates AS ( + SELECT + device_id, + event_date, + SUM(count_motion_detected) AS count_motion_detected, + SUM(count_presence_detected) AS count_presence_detected, + SUM(count_total_presence_detected) AS count_total_presence_detected + FROM table_final + GROUP BY device_id, event_date +) + +INSERT INTO public."presence-sensor-daily-detection" ( + device_uuid, + event_date, + count_motion_detected, + count_presence_detected, + count_total_presence_detected +) +SELECT + device_id, + event_date, + count_motion_detected, + count_presence_detected, + count_total_presence_detected +FROM daily_aggregates +ON CONFLICT (device_uuid, event_date) DO UPDATE +SET + count_motion_detected = EXCLUDED.count_motion_detected, + count_presence_detected = EXCLUDED.count_presence_detected, + count_total_presence_detected = EXCLUDED.count_total_presence_detected; diff --git a/libs/common/src/sql/procedures/fact_space_occupancy/procedure_select_fact_daily_space_occupancy.sql b/libs/common/src/sql/procedures/fact_space_occupancy/procedure_select_fact_daily_space_occupancy.sql new file mode 100644 index 0000000..4b084c4 --- /dev/null +++ b/libs/common/src/sql/procedures/fact_space_occupancy/procedure_select_fact_daily_space_occupancy.sql @@ -0,0 +1,19 @@ +-- will return the presence metrics for the days of the selected month +WITH params AS ( + SELECT + TO_DATE(NULLIF($2, ''), 'YYYY-MM') AS month, + string_to_array(NULLIF($4, ''), ',') AS device_ids +) + + SELECT + A.device_uuid, + A.event_date, + A.count_motion_detected, + A.count_presence_detected, + A.count_total_presence_detected + FROM public."presence-sensor-daily-detection" AS A + JOIN params P ON TRUE + WHERE A.device_uuid::text = ANY(P.device_ids) + AND (P.month IS NULL + OR date_trunc('month', A.event_date) = P.month + ) \ No newline at end of file