Reputation: 9564
Say I have a table like the following :
id | key | user_id | value
---------------------------------------
8 | bp_diastolic | 1 | 93.0
7 | bp_systolic | 1 | 128.0
20 | bp_systolic | 2 | 108.0
21 | bp_diastolic | 2 | 76.0
35 | bp_diastolic | 3 | 113.0
34 | bp_systolic | 3 | 101.0
48 | bp_systolic | 4 | 115.0
49 | bp_diastolic | 4 | 77.0
62 | bp_systolic | 5 | 143.0
63 | bp_diastolic | 5 | 104.0
77 | bp_diastolic | 6 | 108.0
76 | bp_systolic | 6 | 144.0
90 | bp_systolic | 7 | 122.0
91 | bp_diastolic | 7 | 81.0
105 | bp_diastolic | 8 | 110.0
104 | bp_systolic | 8 | 146.0
118 | bp_systolic | 9 | 141.0
119 | bp_diastolic | 9 | 72.0
132 | bp_systolic | 10 | 120.0
133 | bp_diastolic | 10 | 107.0
How would I count all of the user_id
s with bp_systolic
below 120 and bp_diastolic
less than 80?
I can't figure out how to do that since the condition applies to two different rows for a single user. In fact, I lack even the words to form a relevant web search for what I want.
Upvotes: 1
Views: 44
Reputation: 656421
If we know that there is at most one entry for each (user_id, key)
- which could be guaranteed by a constraint UNIQUE (user_id, key)
, this should be fastest::
SELECT user_id
FROM tbl
WHERE key = 'bp_systolic' AND value < 120 OR
key = 'bp_diastolic' AND value < 80
GROUP BY 1
HAVING count(*) = 2;
The HAVING
clause is only needed if there can be users with one of the two keys missing.
Upvotes: 5
Reputation: 1269593
You can do this with conditional aggregation in a having
clause, assuming there are only two readings per user.
select user_id
from table t
group by user_id
having sum(case when key = 'bp_systolic' then value end) < 120 and
sum(case when key = 'bp_diastolic' then value end) < 80;
Upvotes: 4