forked from MIT-LCP/mimic-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathventilation_durations.sql
110 lines (105 loc) · 4.19 KB
/
ventilation_durations.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
-- This query extracts the duration of mechanical ventilation
-- The main goal of the query is to aggregate sequential ventilator settings
-- into single mechanical ventilation "events". The start and end time of these
-- events can then be used for various purposes: calculating the total duration
-- of mechanical ventilation, cross-checking values (e.g. PaO2:FiO2 on vent), etc
-- The query's logic is roughly:
-- 1) The presence of a mechanical ventilation setting starts a new ventilation event
-- 2) Any instance of a setting in the next 8 hours continues the event
-- 3) Certain elements end the current ventilation event
-- a) documented extubation ends the current ventilation
-- b) initiation of non-invasive vent and/or oxygen ends the current vent
-- See the ventilation_classification.sql query for step 1 of the above.
-- This query has the logic for converting events into durations.
with vd0 as
(
select
icustay_id
-- this carries over the previous charttime which had a mechanical ventilation event
, case
when MechVent=1 then
LAG(CHARTTIME, 1) OVER (partition by icustay_id, MechVent order by charttime)
else null
end as charttime_lag
, charttime
, MechVent
, OxygenTherapy
, Extubated
, SelfExtubated
from `physionet-data.mimiciii_derived.ventilation_classification`
)
, vd1 as
(
select
icustay_id
, charttime_lag
, charttime
, MechVent
, OxygenTherapy
, Extubated
, SelfExtubated
-- if this is a mechanical ventilation event, we calculate the time since the last event
, case
-- if the current observation indicates mechanical ventilation is present
-- calculate the time since the last vent event
when MechVent=1 then
DATETIME_DIFF(CHARTTIME, charttime_lag, MINUTE)/60
else null
end as ventduration
, LAG(Extubated,1)
OVER
(
partition by icustay_id, case when MechVent=1 or Extubated=1 then 1 else 0 end
order by charttime
) as ExtubatedLag
-- now we determine if the current mech vent event is a "new", i.e. they've just been intubated
, case
-- if there is an extubation flag, we mark any subsequent ventilation as a new ventilation event
--when Extubated = 1 then 0 -- extubation is *not* a new ventilation event, the *subsequent* row is
when
LAG(Extubated,1)
OVER
(
partition by icustay_id, case when MechVent=1 or Extubated=1 then 1 else 0 end
order by charttime
)
= 1 then 1
-- if patient has initiated oxygen therapy, and is not currently vented, start a newvent
when MechVent = 0 and OxygenTherapy = 1 then 1
-- if there is less than 8 hours between vent settings, we do not treat this as a new ventilation event
when CHARTTIME > DATETIME_ADD(charttime_lag, INTERVAL '8' HOUR)
then 1
else 0
end as newvent
-- use the staging table with only vent settings from chart events
FROM vd0 ventsettings
)
, vd2 as
(
select vd1.*
-- create a cumulative sum of the instances of new ventilation
-- this results in a monotonic integer assigned to each instance of ventilation
, case when MechVent=1 or Extubated = 1 then
SUM( newvent )
OVER ( partition by icustay_id order by charttime )
else null end
as ventnum
--- now we convert CHARTTIME of ventilator settings into durations
from vd1
)
-- create the durations for each mechanical ventilation instance
select icustay_id
-- regenerate ventnum so it's sequential
, ROW_NUMBER() over (partition by icustay_id order by ventnum) as ventnum
, min(charttime) as starttime
, max(charttime) as endtime
, DATETIME_DIFF(max(charttime), min(charttime), MINUTE)/60 AS duration_hours
from vd2
group by icustay_id, vd2.ventnum
having min(charttime) != max(charttime)
-- patient had to be mechanically ventilated at least once
-- i.e. max(mechvent) should be 1
-- this excludes a frequent situation of NIV/oxygen before intub
-- in these cases, ventnum=0 and max(mechvent)=0, so they are ignored
and max(mechvent) = 1
order by icustay_id, ventnum