mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-16 02:36:19 +00:00
Compare commits
1 Commits
ef21b589c0
...
DATA-bug-f
Author | SHA1 | Date | |
---|---|---|---|
6c15ce77fe |
@ -109,7 +109,8 @@ select space_id,
|
|||||||
FROM final_data
|
FROM final_data
|
||||||
ON CONFLICT (space_uuid, event_date) DO UPDATE
|
ON CONFLICT (space_uuid, event_date) DO UPDATE
|
||||||
SET
|
SET
|
||||||
occupancy_percentage = EXCLUDED.occupancy_percentage;
|
occupancy_percentage = EXCLUDED.occupancy_percentage,
|
||||||
|
occupied_seconds = EXCLUDED.occupied_seconds;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -18,10 +18,9 @@ WITH params AS (
|
|||||||
ON p.uuid = d.product_device_uuid
|
ON p.uuid = d.product_device_uuid
|
||||||
WHERE p.cat_name = 'hps'
|
WHERE p.cat_name = 'hps'
|
||||||
AND l.code = 'presence_state'
|
AND l.code = 'presence_state'
|
||||||
),
|
)
|
||||||
|
|
||||||
-- Step 2: Identify periods when device reports "none"
|
, device_none_periods AS (
|
||||||
device_none_periods AS (
|
|
||||||
SELECT
|
SELECT
|
||||||
space_id,
|
space_id,
|
||||||
device_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
|
LEAD(event_time) OVER (PARTITION BY device_id ORDER BY event_time) AS empty_until
|
||||||
FROM start_date
|
FROM start_date
|
||||||
WHERE value = 'none'
|
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
|
SELECT
|
||||||
space_id,
|
space_id,
|
||||||
GREATEST(empty_from, DATE_TRUNC('day', empty_from)) AS clipped_from,
|
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
|
LEAST(empty_until, DATE_TRUNC('day', empty_until) + INTERVAL '1 day') AS clipped_until
|
||||||
FROM device_none_periods
|
FROM device_none_periods
|
||||||
WHERE empty_until IS NOT NULL
|
WHERE empty_until IS NOT NULL
|
||||||
),
|
)
|
||||||
|
|
||||||
-- Step 4: Break multi-day periods into daily intervals
|
, generated_daily_intervals AS (
|
||||||
generated_daily_intervals AS (
|
|
||||||
SELECT
|
SELECT
|
||||||
space_id,
|
space_id,
|
||||||
gs::date AS day,
|
gs::date AS day,
|
||||||
@ -50,10 +47,9 @@ generated_daily_intervals AS (
|
|||||||
LEAST(clipped_until, gs + INTERVAL '1 day') AS interval_end
|
LEAST(clipped_until, gs + INTERVAL '1 day') AS interval_end
|
||||||
FROM clipped_device_none_periods,
|
FROM clipped_device_none_periods,
|
||||||
LATERAL generate_series(DATE_TRUNC('day', clipped_from), DATE_TRUNC('day', clipped_until), INTERVAL '1 day') AS gs
|
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
|
SELECT
|
||||||
space_id,
|
space_id,
|
||||||
day,
|
day,
|
||||||
@ -69,20 +65,18 @@ merged_intervals AS (
|
|||||||
FROM generated_daily_intervals
|
FROM generated_daily_intervals
|
||||||
) sub
|
) sub
|
||||||
WHERE prev_end IS NULL OR interval_start > prev_end
|
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
|
SELECT
|
||||||
space_id,
|
space_id,
|
||||||
day AS missing_date,
|
day AS missing_date,
|
||||||
SUM(EXTRACT(EPOCH FROM (interval_end - interval_start))) AS total_missing_seconds
|
SUM(EXTRACT(EPOCH FROM (interval_end - interval_start))) AS total_missing_seconds
|
||||||
FROM merged_intervals
|
FROM merged_intervals
|
||||||
GROUP BY space_id, day
|
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
|
SELECT
|
||||||
space_id,
|
space_id,
|
||||||
missing_date as event_date,
|
missing_date as event_date,
|
||||||
@ -91,27 +85,32 @@ occupied_seconds_per_day AS (
|
|||||||
FROM missing_seconds_per_day
|
FROM missing_seconds_per_day
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Final Output
|
|
||||||
, final_data as (
|
, final_data as (
|
||||||
SELECT occupied_seconds_per_day.space_id,
|
SELECT
|
||||||
occupied_seconds_per_day.event_date,
|
occupied_seconds_per_day.space_id,
|
||||||
occupied_seconds_per_day.occupancy_percentage
|
occupied_seconds_per_day.event_date,
|
||||||
FROM occupied_seconds_per_day
|
total_occupied_seconds,
|
||||||
join params p on true
|
occupancy_percentage
|
||||||
and p.space_id = occupied_seconds_per_day.space_id
|
FROM occupied_seconds_per_day
|
||||||
and p.event_date = occupied_seconds_per_day.event_date
|
JOIN params p
|
||||||
ORDER BY 1,2
|
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" (
|
INSERT INTO public."space-daily-occupancy-duration" (
|
||||||
space_uuid,
|
space_uuid,
|
||||||
event_date,
|
event_date,
|
||||||
|
occupied_seconds,
|
||||||
occupancy_percentage
|
occupancy_percentage
|
||||||
)
|
)
|
||||||
select space_id,
|
SELECT
|
||||||
event_date,
|
space_id,
|
||||||
occupancy_percentage
|
event_date,
|
||||||
|
total_occupied_seconds,
|
||||||
|
occupancy_percentage
|
||||||
FROM final_data
|
FROM final_data
|
||||||
ON CONFLICT (space_uuid, event_date) DO UPDATE
|
ON CONFLICT (space_uuid, event_date) DO UPDATE
|
||||||
SET
|
SET
|
||||||
occupancy_percentage = EXCLUDED.occupancy_percentage;
|
occupied_seconds = EXCLUDED.occupied_seconds,
|
||||||
|
occupancy_percentage = EXCLUDED.occupancy_percentage;
|
||||||
|
Reference in New Issue
Block a user