Files
mimic-iv-concepts-port/sql/sepsis/blood_gas_arterial.sql

231 lines
10 KiB
MySQL
Raw Normal View History

2026-05-05 10:22:17 +02:00
-- ------------------------------------------------------------------
-- All-time arterial blood-gas pivot (PaO2 / FiO2 ratio at every gas).
--
-- This script is a fusion of the upstream MIMIC-III concepts_postgres
-- files
-- firstday/blood_gas_first_day.sql
-- firstday/blood_gas_first_day_arterial.sql
-- with their day-1 time predicate removed, so we get one row per
-- (icustay_id, charttime) for the entire ICU stay.
--
-- Output table: blood_gas_arterial
-- Output cols : subject_id, hadm_id, icustay_id, charttime,
-- specimen, specimen_pred, specimen_prob,
-- so2, spo2, po2, pco2, fio2_chartevents, fio2,
-- aado2, aado2_calc, pao2fio2, ph, baseexcess,
-- bicarbonate, totalco2, hematocrit, hemoglobin,
-- carboxyhemoglobin, methemoglobin, chloride, calcium,
-- temperature, potassium, sodium, lactate, glucose,
-- intubated, tidalvolume, ventilationrate, ventilator,
-- peep, o2flow, requiredo2
--
-- Restricted to *arterial* samples (specimen = 'ART' or
-- specimen_prob > 0.75).
-- ------------------------------------------------------------------
DROP TABLE IF EXISTS blood_gas_arterial;
CREATE TABLE blood_gas_arterial AS
WITH bg_pvt AS
(
SELECT ie.subject_id, ie.hadm_id, ie.icustay_id
, CASE
WHEN itemid = 50800 THEN 'SPECIMEN'
WHEN itemid = 50801 THEN 'AADO2'
WHEN itemid = 50802 THEN 'BASEEXCESS'
WHEN itemid = 50803 THEN 'BICARBONATE'
WHEN itemid = 50804 THEN 'TOTALCO2'
WHEN itemid = 50805 THEN 'CARBOXYHEMOGLOBIN'
WHEN itemid = 50806 THEN 'CHLORIDE'
WHEN itemid = 50808 THEN 'CALCIUM'
WHEN itemid = 50809 THEN 'GLUCOSE'
WHEN itemid = 50810 THEN 'HEMATOCRIT'
WHEN itemid = 50811 THEN 'HEMOGLOBIN'
WHEN itemid = 50812 THEN 'INTUBATED'
WHEN itemid = 50813 THEN 'LACTATE'
WHEN itemid = 50814 THEN 'METHEMOGLOBIN'
WHEN itemid = 50815 THEN 'O2FLOW'
WHEN itemid = 50816 THEN 'FIO2'
WHEN itemid = 50817 THEN 'SO2'
WHEN itemid = 50818 THEN 'PCO2'
WHEN itemid = 50819 THEN 'PEEP'
WHEN itemid = 50820 THEN 'PH'
WHEN itemid = 50821 THEN 'PO2'
WHEN itemid = 50822 THEN 'POTASSIUM'
WHEN itemid = 50823 THEN 'REQUIREDO2'
WHEN itemid = 50824 THEN 'SODIUM'
WHEN itemid = 50825 THEN 'TEMPERATURE'
WHEN itemid = 50826 THEN 'TIDALVOLUME'
WHEN itemid = 50827 THEN 'VENTILATIONRATE'
WHEN itemid = 50828 THEN 'VENTILATOR'
ELSE NULL
END AS label
, le.charttime
, le.value
, CASE
WHEN valuenum <= 0 AND itemid != 50802 THEN NULL
WHEN itemid = 50810 AND valuenum > 100 THEN NULL
WHEN itemid = 50816 AND valuenum < 20 THEN NULL
WHEN itemid = 50816 AND valuenum > 100 THEN NULL
WHEN itemid = 50817 AND valuenum > 100 THEN NULL
WHEN itemid = 50815 AND valuenum > 70 THEN NULL
WHEN itemid = 50821 AND valuenum > 800 THEN NULL
ELSE valuenum
END AS valuenum
FROM icustays ie
INNER JOIN labevents le
ON le.subject_id = ie.subject_id
AND le.hadm_id = ie.hadm_id
AND le.charttime BETWEEN ie.intime AND ie.outtime
AND le.itemid IN (
50800,50801,50802,50803,50804,50805,50806,50807,50808,50809
, 50810,50811,50812,50813,50814,50815,50816,50817,50818,50819
, 50820,50821,50822,50823,50824,50825,50826,50827,50828
, 51545
)
)
, bg AS
(
SELECT subject_id, hadm_id, icustay_id, charttime
, MAX(CASE WHEN label = 'SPECIMEN' THEN value END) AS specimen
, MAX(CASE WHEN label = 'AADO2' THEN valuenum END) AS aado2
, MAX(CASE WHEN label = 'BASEEXCESS' THEN valuenum END) AS baseexcess
, MAX(CASE WHEN label = 'BICARBONATE' THEN valuenum END) AS bicarbonate
, MAX(CASE WHEN label = 'TOTALCO2' THEN valuenum END) AS totalco2
, MAX(CASE WHEN label = 'CARBOXYHEMOGLOBIN' THEN valuenum END) AS carboxyhemoglobin
, MAX(CASE WHEN label = 'CHLORIDE' THEN valuenum END) AS chloride
, MAX(CASE WHEN label = 'CALCIUM' THEN valuenum END) AS calcium
, MAX(CASE WHEN label = 'GLUCOSE' THEN valuenum END) AS glucose
, MAX(CASE WHEN label = 'HEMATOCRIT' THEN valuenum END) AS hematocrit
, MAX(CASE WHEN label = 'HEMOGLOBIN' THEN valuenum END) AS hemoglobin
, MAX(CASE WHEN label = 'INTUBATED' THEN valuenum END) AS intubated
, MAX(CASE WHEN label = 'LACTATE' THEN valuenum END) AS lactate
, MAX(CASE WHEN label = 'METHEMOGLOBIN' THEN valuenum END) AS methemoglobin
, MAX(CASE WHEN label = 'O2FLOW' THEN valuenum END) AS o2flow
, MAX(CASE WHEN label = 'FIO2' THEN valuenum END) AS fio2
, MAX(CASE WHEN label = 'SO2' THEN valuenum END) AS so2
, MAX(CASE WHEN label = 'PCO2' THEN valuenum END) AS pco2
, MAX(CASE WHEN label = 'PEEP' THEN valuenum END) AS peep
, MAX(CASE WHEN label = 'PH' THEN valuenum END) AS ph
, MAX(CASE WHEN label = 'PO2' THEN valuenum END) AS po2
, MAX(CASE WHEN label = 'POTASSIUM' THEN valuenum END) AS potassium
, MAX(CASE WHEN label = 'REQUIREDO2' THEN valuenum END) AS requiredo2
, MAX(CASE WHEN label = 'SODIUM' THEN valuenum END) AS sodium
, MAX(CASE WHEN label = 'TEMPERATURE' THEN valuenum END) AS temperature
, MAX(CASE WHEN label = 'TIDALVOLUME' THEN valuenum END) AS tidalvolume
, MAX(CASE WHEN label = 'VENTILATIONRATE' THEN valuenum END) AS ventilationrate
, MAX(CASE WHEN label = 'VENTILATOR' THEN valuenum END) AS ventilator
FROM bg_pvt
GROUP BY subject_id, hadm_id, icustay_id, charttime
)
, stg_spo2 AS
(
SELECT subject_id, hadm_id, icustay_id, charttime
, MAX(CASE WHEN valuenum <= 0 OR valuenum > 100 THEN NULL ELSE valuenum END) AS spo2
FROM chartevents
WHERE itemid IN (646, 220277)
GROUP BY subject_id, hadm_id, icustay_id, charttime
)
, stg_fio2 AS
(
SELECT subject_id, hadm_id, icustay_id, charttime
, MAX(
CASE
WHEN itemid = 223835 THEN
CASE
WHEN valuenum > 0 AND valuenum <= 1 THEN valuenum * 100
WHEN valuenum > 1 AND valuenum < 21 THEN NULL
WHEN valuenum >= 21 AND valuenum <= 100 THEN valuenum
ELSE NULL
END
WHEN itemid IN (3420, 3422) THEN valuenum
WHEN itemid = 190 AND valuenum > 0.20 AND valuenum < 1
THEN valuenum * 100
ELSE NULL
END
) AS fio2_chartevents
FROM chartevents
WHERE itemid IN (3420, 190, 223835, 3422)
AND COALESCE(error, 0) = 0
GROUP BY subject_id, hadm_id, icustay_id, charttime
)
, stg2 AS
(
SELECT bg.*
, ROW_NUMBER() OVER (
PARTITION BY bg.icustay_id, bg.charttime
ORDER BY s1.charttime DESC
) AS lastrowspo2
, s1.spo2
FROM bg
LEFT JOIN stg_spo2 s1
ON bg.icustay_id = s1.icustay_id
AND s1.charttime >= DATETIME_SUB(bg.charttime, INTERVAL '2' HOUR)
AND s1.charttime <= bg.charttime
WHERE bg.po2 IS NOT NULL
)
, stg3 AS
(
SELECT stg2.*
, ROW_NUMBER() OVER (
PARTITION BY stg2.icustay_id, stg2.charttime
ORDER BY s2.charttime DESC
) AS lastrowfio2
, s2.fio2_chartevents
, 1 / (1 + EXP(-(-0.02544
+ 0.04598 * po2
+ COALESCE(-0.15356 * spo2 , -0.15356 * 97.49420 + 0.13429)
+ COALESCE( 0.00621 * s2.fio2_chartevents, 0.00621 * 51.49550 + -0.24958)
+ COALESCE( 0.10559 * hemoglobin , 0.10559 * 10.32307 + 0.05954)
+ COALESCE( 0.13251 * so2 , 0.13251 * 93.66539 + -0.23172)
+ COALESCE(-0.01511 * pco2 , -0.01511 * 42.08866 + -0.01630)
+ COALESCE( 0.01480 * fio2 , 0.01480 * 63.97836 + -0.31142)
+ COALESCE(-0.00200 * aado2 , -0.00200 * 442.21186 + -0.01328)
+ COALESCE(-0.03220 * bicarbonate , -0.03220 * 22.96894 + -0.06535)
+ COALESCE( 0.05384 * totalco2 , 0.05384 * 24.72632 + -0.01405)
+ COALESCE( 0.08202 * lactate , 0.08202 * 3.06436 + 0.06038)
+ COALESCE( 0.10956 * ph , 0.10956 * 7.36233 + -0.00617)
+ COALESCE( 0.00848 * o2flow , 0.00848 * 7.59362 + -0.35803)
))) AS specimen_prob
FROM stg2
LEFT JOIN stg_fio2 s2
ON stg2.icustay_id = s2.icustay_id
AND s2.charttime BETWEEN DATETIME_SUB(stg2.charttime, INTERVAL '4' HOUR)
AND stg2.charttime
WHERE stg2.lastrowspo2 = 1
)
SELECT subject_id, hadm_id, icustay_id, charttime
, specimen
, CASE
WHEN specimen IS NOT NULL THEN specimen
WHEN specimen_prob > 0.75 THEN 'ART'
ELSE NULL
END AS specimen_pred
, specimen_prob
, so2, spo2, po2, pco2
, fio2_chartevents, fio2
, aado2
, CASE
WHEN po2 IS NOT NULL
AND pco2 IS NOT NULL
AND COALESCE(fio2, fio2_chartevents) IS NOT NULL
THEN (COALESCE(fio2, fio2_chartevents) / 100) * (760 - 47) - (pco2 / 0.8) - po2
ELSE NULL
END AS aado2_calc
, CASE
WHEN po2 IS NOT NULL AND COALESCE(fio2, fio2_chartevents) IS NOT NULL
THEN 100 * po2 / COALESCE(fio2, fio2_chartevents)
ELSE NULL
END AS pao2fio2
, ph, baseexcess, bicarbonate, totalco2
, hematocrit, hemoglobin, carboxyhemoglobin, methemoglobin
, chloride, calcium, temperature, potassium, sodium, lactate, glucose
, intubated, tidalvolume, ventilationrate, ventilator
, peep, o2flow, requiredo2
FROM stg3
WHERE lastrowfio2 = 1
AND (specimen = 'ART' OR specimen_prob > 0.75);
CREATE INDEX IF NOT EXISTS blood_gas_arterial_idx
ON blood_gas_arterial (icustay_id, charttime);