SELECT 要求知道需要的列;FROM 要求知道存放的 表(多个表就用join语句进行连接,或者用WITH 语句创建临时 表);WHERE 语句要求 明确查询的目的; GROUP 要求确定 作为第二“索引”的列(这是我个人的一种感觉,第一索引是自然索引,所以称GROUP 形成的为第二索引)。
请结合官方文档进行了解。
MIMIC_IV的模块:
ICU:这个模块自成体系(相对与另外两个模块),之所以这样说是因为其有自己的反映患者"结局"的表格,即icustays, 其中的列los(length of stay), 是常用的结局指标,相关文档;另外,这个模块中有自己的实验室检查(chartevents), 医学操作(*events),说明表格(d_items)等,这个特点意味着这个模块可以独立进行分析或偶尔地结合hosp等模块的数据进行分析。 **Tips:**表datetimeevent之所以如此命名是因为其value是时间。
core:mimic_core.admissions是可以看作是收录患者结局的表格,其中的死亡时间和出院时间可以为我们提供计算患者结局的数据。(hospital_expire_flag这个特征提供了患者是否发生院内死亡),相关文档。
hosp:根据研究方向,如果是对疾病对患者预后的影响感兴趣,用到的表格包括,实验室检查(labevents, d_labitems),诊断信息(diagnoses_icd, d_icd_diagnoses, drgcodes);如果是对患者用的药物对患者的预后感兴趣,药物使用(emar,emar_detail)、药物处方(prescriptions,pharmacy),诊断信息 是重要的表格,其它的表格可以暂时列为不重要的表格,相关文档。
尽管数据库提供了很多的表格, 真正用到的就那么几个:
用到的SQL语句的种类也不是很多,也有一定的模式
一些细节:
不要紧,可以一步一步来
第一步,就我个人来说,先找到感兴趣的某种疾病,作为整个查询的限定。
select icd_code, icd_version, long_title from mimic_hosp.d_icd_diagnoses where long_title ~* 'myocardial'
这还是从"科研杂录"的文章学习过来的!~*是匹配后面的字符串。
更常见的是根据代码来进行匹配。
第二步,确定我需要什么样的信息以及这些信息存储在哪些表格内;一般需要的信息就是患者的一般信息(年龄,性别等),实验室信息, 治疗信息, 预后信息(死亡等)。mimic IV贴心地在ICU模块中提供了一个lookup 表格来帮助定位以上的信息, d_items。以d(dictionary)开头的表格都是这种信息表,可以下载下来随时查询。
d_items截图,可以看到其linksto一栏指明了信息储存的表格。
hosp模块中也有几个d_开头的表格,其作用是用来查询对应表格(以events结尾的表格)的编码, 其用法类似上面提到的d_icd_diagnoses。其它的表格存储的内容可以从表格的名称来推断。
第三步,制定查询的策略, 之前发表的关于mimic III的一篇文章(doi:10.1145/3368555.3384469)首先将所有的指标提取为patients、vital_labs和interventions 三个表格,可以作为借鉴。
-- This query checks if the patient had AKI according to KDIGO.
-- AKI is calculated every time a creatinine or urine output measurement occurs.
-- Baseline creatinine is defined as the lowest creatinine in the past 7 days.
-- get creatinine stages
with cr_stg AS
(
SELECT
cr.stay_id
, cr.charttime
, cr.creat_low_past_7day
, cr.creat_low_past_48hr
, cr.creat
, case
-- 3x baseline
when cr.creat >= (cr.creat_low_past_7day*3.0) then 3
-- *OR* cr >= 4.0 with associated increase
when cr.creat >= 4
-- For patients reaching Stage 3 by SCr >4.0 mg/dl
-- require that the patient first achieve ... acute increase >= 0.3 within 48 hr
-- *or* an increase of >= 1.5 times baseline
and (cr.creat_low_past_48hr <= 3.7 OR cr.creat >= (1.5*cr.creat_low_past_7day))
then 3
-- TODO: initiation of RRT
when cr.creat >= (cr.creat_low_past_7day*2.0) then 2
when cr.creat >= (cr.creat_low_past_48hr+0.3) then 1
when cr.creat >= (cr.creat_low_past_7day*1.5) then 1
else 0 end as aki_stage_creat
FROM `physionet-data.mimic_derived.kdigo_creatinine` cr
)
-- stages for UO / creat
, uo_stg as
(
select
uo.stay_id
, uo.charttime
, uo.weight
, uo.uo_rt_6hr
, uo.uo_rt_12hr
, uo.uo_rt_24hr
-- AKI stages according to urine output
, CASE
WHEN uo.uo_rt_6hr IS NULL THEN NULL
-- require patient to be in ICU for at least 6 hours to stage UO
WHEN uo.charttime <= DATETIME_ADD(ie.intime, INTERVAL '6' HOUR) THEN 0
-- require the UO rate to be calculated over half the period
-- i.e. for uo rate over 24 hours, require documentation at least 12 hr apart
WHEN uo.uo_tm_24hr >= 11 AND uo.uo_rt_24hr < 0.3 THEN 3
WHEN uo.uo_tm_12hr >= 5 AND uo.uo_rt_12hr = 0 THEN 3
WHEN uo.uo_tm_12hr >= 5 AND uo.uo_rt_12hr < 0.5 THEN 2
WHEN uo.uo_tm_6hr >= 2 AND uo.uo_rt_6hr < 0.5 THEN 1
ELSE 0 END AS aki_stage_uo
from `physionet-data.mimic_derived.kdigo_uo` uo
INNER JOIN `physionet-data.mimic_icu.icustays` ie
ON uo.stay_id = ie.stay_id
)
-- get all charttimes documented
, tm_stg AS
(
SELECT
stay_id, charttime
FROM cr_stg
UNION DISTINCT
SELECT
stay_id, charttime
FROM uo_stg
)
select
ie.subject_id
, ie.hadm_id
, ie.stay_id
, tm.charttime
, cr.creat_low_past_7day
, cr.creat_low_past_48hr
, cr.creat
, cr.aki_stage_creat
, uo.uo_rt_6hr
, uo.uo_rt_12hr
, uo.uo_rt_24hr
, uo.aki_stage_uo
-- Classify AKI using both creatinine/urine output criteria
, GREATEST(
COALESCE(cr.aki_stage_creat,0),
COALESCE(uo.aki_stage_uo,0)
) AS aki_stage
FROM `physionet-data.mimic_icu.icustays` ie
-- get all possible charttimes as listed in tm_stg
LEFT JOIN tm_stg tm
ON ie.stay_id = tm.stay_id
LEFT JOIN cr_stg cr
ON ie.stay_id = cr.stay_id
AND tm.charttime = cr.charttime
LEFT JOIN uo_stg uo
ON ie.stay_id = uo.stay_id
AND tm.charttime = uo.charttime
;