@@ -103,6 +103,68 @@ src-stats:
103103 m.visit_occurrence_id,
104104 v.visit_start_datetime,
105105 v.visit_end_datetime) subquery;
106+ - name : bp_sys_relative_change_stats
107+ # For each patient + visit + BP type, sort measurements in time,
108+ # compute |xₜ − xₜ₋₁| / xₜ₋₁ for each step,
109+ # then average those within that visit.
110+ # Finally, average that visit-level metric across the population.
111+ query : >
112+ WITH bp AS (
113+ SELECT
114+ p.person_id,
115+ p.gender_concept_id,
116+ v.visit_occurrence_id,
117+ EXTRACT(YEAR FROM v.visit_start_datetime) - p.year_of_birth AS age,
118+ m.measurement_concept_id,
119+ m.value_as_number,
120+ m.measurement_datetime
121+ FROM mimic.person p
122+ JOIN mimic.visit_occurrence v
123+ ON p.person_id = v.person_id
124+ JOIN mimic.measurement m
125+ ON m.visit_occurrence_id = v.visit_occurrence_id
126+ WHERE m.measurement_concept_id IN (21492239) -- systolic
127+ ),
128+ bp_with_lag AS (
129+ SELECT
130+ bp.*,
131+ LAG(value_as_number) OVER (
132+ PARTITION BY person_id, visit_occurrence_id, measurement_concept_id
133+ ORDER BY measurement_datetime
134+ ) AS prev_value
135+ FROM bp
136+ ),
137+ visit_level_rel_var AS (
138+ SELECT
139+ person_id,
140+ gender_concept_id,
141+ age,
142+ visit_occurrence_id,
143+ measurement_concept_id,
144+ -- average relative change within this visit
145+ AVG( ABS(value_as_number - prev_value)
146+ / NULLIF(prev_value, 0) ) AS avg_rel_var
147+ FROM bp_with_lag
148+ WHERE prev_value IS NOT NULL -- skip first measurement in each visit
149+ GROUP BY
150+ person_id,
151+ gender_concept_id,
152+ age,
153+ visit_occurrence_id,
154+ measurement_concept_id
155+ )
156+ SELECT
157+ gender_concept_id,
158+ AVG(CASE WHEN measurement_concept_id = 21492239 AND age > 60
159+ THEN avg_rel_var END)::float4 AS avg_over_60_systolic_rel_var,
160+ AVG(CASE WHEN measurement_concept_id = 21492239 AND age <= 60
161+ THEN avg_rel_var END)::float4 AS avg_under_60_systolic_rel_var,
162+ STDDEV(CASE WHEN measurement_concept_id = 21492239 AND age > 60
163+ THEN avg_rel_var END)::float4 AS stddev_over_60_systolic_rel_var,
164+ STDDEV(CASE WHEN measurement_concept_id = 21492239 AND age <= 60
165+ THEN avg_rel_var END)::float4 AS stddev_under_60_systolic_rel_var
166+ FROM visit_level_rel_var
167+ GROUP BY gender_concept_id;
106168tables :
107169 person :
108170 num_rows_per_pass : 0
0 commit comments