There are two Postgres tables, one has the work roster with the planned times, the other has times the work was actually carried out. All times are stored as timestamps, the tables are linked with a job number in a 1:1 relationship. There are three KPIs around the work timing:
The desired outcome is a list of job numbers and a pass/fail string for each KPI. KPI report is currently run once a month, but we are looking to have this connected to a live dashboard. Volume is currently low (6500 rows/month), but has been rising at about 5-10% per month.
table_a
job_no | rostered_start | rostered_end |
---|---|---|
836435 | 2022-11-01 07:00:00.000 | 2022-11-01 09:00:00.000 |
836436 | 2022-11-01 07:00:00.000 | 2022-11-01 10:00:00.000 |
836437 | 2022-11-01 08:15:00.000 | 2022-11-01 10:15:00.000 |
table_b
job_no | actual_start | actual_end |
---|---|---|
836435 | 2022-11-01 07:10:00.000 | 2022-11-01 09:10:00.000 |
836436 | 2022-11-01 08:53:00.000 | 2022-11-01 11:54:00.000 |
836437 | 2022-11-01 07:58:00.000 | 2022-11-01 09:58:00.000 |
Result
job_no | kpi_start | kpi_end | kpi_startend |
---|---|---|---|
836435 | PASS | PASS | Both Pass |
836436 | FAIL | FAIL | Both Fail |
836437 | FAIL | FAIL | Both Fail |
In the absence of an abs(interval), currently I have two candidates for comparing the two times:
CASE
WHEN ABS(TO_CHAR((table_a.rostered_start - table_b.actual_start) , 'MI')::integer) <= 15
THEN 'PASS'::TEXT
ELSE 'FAIL'::TEXT
END AS start_time_check
or
CASE
WHEN table_b.actual_start <= (table_a.rostered_start + '00:15:00'::INTERVAL)
AND table_b.actual_start >= (table_a.rostered_start - '00:15:00'::INTERVAL)
THEN 'PASS'::TEXT
ELSE 'FAIL'::TEXT
END AS start_time_check
At the scale I'm working at it seems like it doesn't matter which one I choose, but:
SELECT *, kpi_start AND kpi_end AS kpi_startend
FROM (
SELECT job_no
, b.actual_start - a.rostered_start BETWEEN interval '- 15 min' AND interval '15 min' AS kpi_start
, b.actual_end - a.rostered_end BETWEEN interval '- 15 min' AND interval '15 min' AS kpi_end
FROM tbl_a a
JOIN tbl_b b USING (job_no)
) sub;
Using more natural boolean
values instead of PASS / FAIL. Easy to translate.
There is no built-in abs()
function for the interval
data type, just abs(numeric_type)
. But the BETWEEN... AND...
construct is at least as performant and simple enough.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.