Skip to content

Commit c070cb5

Browse files
committed
Add Active Patient Report with Patient Tags documentation and SQL query
1 parent cd1d68c commit c070cb5

1 file changed

Lines changed: 133 additions & 0 deletions

File tree

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
2+
# Active Patient Report with Patient Tags
3+
4+
> Currently active patients at Arike with zone / place-of-care tags with the most relevant encounter or upcoming appointment date
5+
6+
## Purpose
7+
8+
Identifies the set of **currently active patients** at Arike and their zone and place-of-care , plus a single `date` column that reflects either their most recent encounter (within the last 100 days) or their earliest upcoming appointment (within the next 100 days).
9+
10+
An "active patient" is defined as one who:
11+
12+
- is **not deceased**, and
13+
- does **not** carry the exclusion tag (`tag_id = 70`), and
14+
- either has an encounter at facility 2 in the last 100 days, **or** has an upcoming booked / checked-in / in-consultation appointment at facility 2 in the next 100 days.
15+
16+
17+
18+
## Parameters
19+
20+
| Parameter | Type | Description | Example |
21+
|-----------|------|-------------|---------|
22+
| `zone_filter` | TEXT | Filter by resolved zone tag display (exact match) | `'Zone A'` |
23+
| `place_of_care` | TEXT | Filter by resolved place-of-care tag display (exact match) | `'Home'` |
24+
25+
---
26+
27+
## Query
28+
29+
```sql
30+
WITH active_patients AS (
31+
SELECT DISTINCT
32+
ep.id AS patient_id,
33+
ep.name AS patient_name,
34+
ep.gender,
35+
ep.phone_number,
36+
pi.value AS adm,
37+
ep.instance_tags
38+
FROM emr_patient ep
39+
LEFT JOIN emr_patientidentifier pi
40+
ON ep.id = pi.patient_id
41+
AND pi.config_id = 2
42+
WHERE ep.deceased_datetime IS NULL
43+
AND NOT (70 = ANY(ep.instance_tags))
44+
AND (
45+
EXISTS (
46+
SELECT 1
47+
FROM emr_encounter ee
48+
WHERE ee.patient_id = ep.id
49+
AND ee.created_date >= CURRENT_DATE - INTERVAL '100 days'
50+
AND ee.facility_id = 2
51+
AND ee.deleted = FALSE
52+
)
53+
OR
54+
EXISTS (
55+
SELECT 1
56+
FROM emr_tokenbooking tb
57+
JOIN emr_tokenslot ts
58+
ON tb.token_slot_id = ts.id
59+
JOIN emr_schedulableresource sbr
60+
ON ts.resource_id = sbr.id
61+
WHERE tb.patient_id = ep.id
62+
AND ts.start_datetime >= CURRENT_DATE
63+
AND ts.start_datetime < CURRENT_DATE + INTERVAL '100 days'
64+
AND sbr.facility_id = 2
65+
AND tb.deleted = FALSE
66+
AND ts.deleted = FALSE
67+
AND tb.status IN ('booked', 'checked_in', 'in_consultation')
68+
)
69+
)
70+
),
71+
patient_tags AS (
72+
SELECT
73+
ap.patient_id,
74+
COALESCE(MAX(CASE WHEN et.parent_id = 55 THEN et.display END), 'unassigned') AS zone,
75+
COALESCE(MAX(CASE WHEN et.parent_id = 71 THEN et.display END), 'unassigned') AS place_of_care
76+
FROM active_patients ap
77+
LEFT JOIN LATERAL unnest(ap.instance_tags) AS tag_id ON TRUE
78+
LEFT JOIN emr_tagconfig et
79+
ON et.id = tag_id
80+
AND et.deleted = FALSE
81+
GROUP BY ap.patient_id
82+
)
83+
SELECT
84+
ap.patient_name,
85+
ap.phone_number,
86+
ap.adm,
87+
ap.gender,
88+
pt.zone,
89+
pt.place_of_care,
90+
COALESCE(
91+
(SELECT MAX(ee.created_date)
92+
FROM emr_encounter ee
93+
WHERE ee.patient_id = ap.patient_id
94+
AND ee.created_date >= CURRENT_DATE - INTERVAL '100 days'
95+
AND ee.facility_id = 2),
96+
(SELECT MIN(ts.start_datetime)
97+
FROM emr_tokenbooking tb
98+
JOIN emr_tokenslot ts
99+
ON tb.token_slot_id = ts.id
100+
JOIN emr_schedulableresource sbr
101+
ON ts.resource_id = sbr.id
102+
WHERE tb.patient_id = ap.patient_id
103+
AND ts.start_datetime >= CURRENT_DATE
104+
AND ts.start_datetime < CURRENT_DATE + INTERVAL '100 days'
105+
AND sbr.facility_id = 2
106+
AND tb.deleted = FALSE
107+
AND ts.deleted = FALSE
108+
AND tb.status IN ('booked', 'checked_in', 'in_consultation'))
109+
) AS date
110+
FROM active_patients ap
111+
LEFT JOIN patient_tags pt
112+
ON pt.patient_id = ap.patient_id
113+
WHERE 1=1
114+
--[[AND pt.zone = {{zone_filter}}]]
115+
--[[AND pt.place_of_care = {{place_of_care}}]]
116+
ORDER BY ap.patient_name;
117+
```
118+
119+
## Notes
120+
121+
- **Active-patient definition:** Encoded in the `active_patients` CTE — not deceased, not carrying tag `70`, and either has a recent encounter (last 100 days) **or** an upcoming appointment (next 100 days) at `facility_id = 2` (Arike).
122+
- **Hardcoded IDs:**
123+
- `facility_id = 2` — Arike facility.
124+
- `pi.config_id = 2` — ADM patient identifier configuration.
125+
- `70` — exclusion instance tag (patients carrying this tag are omitted).
126+
- `parent_id = 55` — parent tag for **zone**.
127+
- `parent_id = 71` — parent tag for **place of care**.
128+
Update any of these if the underlying configuration changes.
129+
- **Metabase filters:**
130+
- `[[AND pt.zone = {{zone_filter}}]]` and `[[AND pt.place_of_care = {{place_of_care}}]]` — exact-match filters applied on the resolved tag columns.
131+
- Results are ordered alphabetically by patient name.
132+
133+
*Last updated: 2026-07-07*

0 commit comments

Comments
 (0)