I got some problem where I can't really wrap my head around.
I have a table with timestamps for ventilation duration which contains the whole duration of different episodes in minutes where the patient was ventilated and some other data a key to with the patient's case ID.
Here is an example of the table:
PK | CaseID | Duration | Begin | End |
---|---|---|---|---|
1 | 1 | 45860 | 2018-01-13 12:15:00 | 2018-02-14 08:35:00 |
2 | 1 | 132 | 2018-01-11 11:45:00 | 2018-01-13 12:15:00 |
So as you see one case can have multiple rows in this table. Now in another table I have the departments and stations where the patient / case was during their stay in hospital (from admission to discharge) - also with timestamps:
PK | CaseID | Begin | End | StationID |
---|---|---|---|---|
1 | 1 | 2018-01-13 11:53:00 | 2018-01-13 12:11:00 | 123 |
2 | 1 | 2018-01-13 12:11:00 | 2018-02-18 10:59:00 | 123 |
3 | 1 | 2018-02-25 09:15:00 | 2018-02-26 11:27:00 | 123 |
4 | 1 | 2018-02-26 11:27:00 | 2018-03-01 10:04:00 | 123 |
5 | 1 | 2018-03-01 11:06:00 | 2018-03-03 14:25:00 | 234 |
Now I'd like to build a query to sum up the ventilation duration on specific stations. As you can see I don't have a station reference in the first table, so I have to compare the timestamps to get the time when we was on this specific station (for example - like here - with ID 123).
I think I get the logic that the beginning of the ventilation must be more than or equal to the beginning of the station's visit and the end has to be less than or equal to the end of the station's visit, but I'm not sure how to deal with those multiple stays (e.g. when re-admissioned).
I came up with the following query which seems to work but the numbers are a bit on the lower side in my opinion:
@set start_date = '01.01.2018 00:00:00'
@set end_date = '31.08.2021 23:59:59'
@set format = 'DD.MM.YYYY HH24:MI:SS'
SELECT
"Year",
SUM("Ventilation Duration") AS "Sum"
FROM
(SELECT
f.CASEID AS "FallID",
SUM(DECODE(fb.DURATION, 20 , ROUND(fb.DURATION / 60, 0), 21, fb.DURATION)) AS "Ventilation Duration",
TO_CHAR(fa.BEGIN, 'DD.MM.YYYY HH24:MI') AS "Begin Station Stay",
TO_CHAR(fb.BEGIN, 'DD.MM.YYYY HH24:MI') AS "Begin Ventilation",
TO_CHAR(fb.END, 'DD.MM.YYYY HH24:MI') AS "End Ventilation",
TO_CHAR(fa.END, 'DD.MM.YYYY HH24:MI') AS "End Station Stay",
oe.STATION_NAME AS "Station",
TO_CHAR(f.DISCHARGE_DATE, 'YYYY') AS "YEAR"
FROM
CASE_VENTLATION fb
INNER JOIN
CASE_STAY fa ON fa.CASEID = fb.CASEID
INNER JOIN
CASE f ON f.CASEID = fb.CASEID
INNER JOIN
STATION oe ON oe.STATIONID = fa.STATIONID
WHERE
f.STORNO_DATUM IS NULL
AND f.DISCHARGE_DATE BETWEEN TO_DATE(:start_date, :format) AND TO_DATE(:end_date, :format)
AND fa.STATIONID = 10097
AND f.CASEMARK IN (38140, 38142)
AND fb.BEGIN >=(SELECT MIN(fa.BEGIN)FROM CASE_STAY fa2 WHERE fa2.CASEID = fb.CASEID AND fa2.STATION_ID = fa.STATION_ID)
AND fb.END <= SELECT MAX(fa.ENDE)FROM CASE_STAY fa2 WHERE fa2.CASEID = fb.CASEID AND fa2.STATION_ID = fa.STATION_ID)
GROUP BY
...
)
GROUP BY "Year"
ORDER BY "Year"
Would you consider this als logically correct or can I write a better WHERE-Condition - especially with the MIN and MAX functions.
Don't mind the aliases, I translated some field names from German so it's easier to understand to what fields in the example they refer.
EDIT: As requested, this is my current result:
Year | Sum |
---|---|
2018 | 23412 |
2019 | 35618 |
2020 | 25633 |
2021 | 19682 |
Problem is, as I said, it's a bit on the lower side and I guess I missed some due to those timestamp overlaps :/.
Any help is greatly appreciated!
Thanks!
CodePudding user response:
To be honest, I am not completely sure whether I got the task correctly but it seems to be interesting, so I'll try. Sorry if I'm wrong.
If all you need is to calculate amount of minutes patients were ventilated on each station, here is what I have:
select st.station_id,
v.caseid,
sum((least(v.end_date, st.end_date) - greatest(v.begin_date, st.begin_date)) * 24 * 60) vent_duration_mins
from vent v
join dep_stat st
on v.caseid = st.caseid
and v.begin_date < st.end_date
and v.end_date > st.begin_date
group by st.station_id,
v.caseid
This case assumes all date columns are of date type, not timestamp