Reputation: 159
I have the following,
CREATE TABLE t (
id int,
events text, -- may be 'HR1', 'HR2', 'HR3', etc Or 'BP'
event_value int
);
events
can be HR1
/HR2
(an id
either has HR1
or HR2
, not both), or any other event: e.g. `BP)id
has several rows.I basically want to select IDs which have, for HR1
or HR2
(depending on which it is used for that ID), all their values in between 50 and 110.
The query for HR1
or HR2
returns a distinct id
and event
if all the groups values are between 50 and 110.
The following table is an example:
ID | event | event value
-----------+---------+-------------
1 'HR1' 80
1 'HR1' 90
1 'HR1' 72
1 'HR1' 91
1 'HR1' 69
1 'BP' 2.3
-
2 'HR1' 90
2 'HR1' 40
2 'HR1' 39
-
3 'HR2' 200
3 'HR2' 230
3 'HR2' 85
-
4 'HR2' 90
4 'HR2' 80
4 'HR2' 90
I want the following output:
subject_id | event
------------+--------
1 'HR1'
4 'HR2'
Upvotes: 1
Views: 1290
Reputation: 46219
I would use NOT EXISTS
and DISTINCT subject_id,event
to make it.
SELECT DISTINCT id,event
FROM t AS t1
WHERE NOT EXISTS(
SELECT 1
FROM t AS t2
WHERE (t2.event_value < 50 OR t2.event_value > 110)
AND t1.id = t2.id
AND t1.event = t2.event
)
AND t1.event in ('HR1','HR2');
Upvotes: 2
Reputation: 94914
You have changed the desired output, which makes this a completely different request. You want one row per subject now, an aggregation:
SELECT id, event
FROM t
WHERE event in ('HR1', 'HR2')
GROUP BY id, event
HAVING count(CASE WHEN event_value NOT BETWEEN 50 AND 110 THEN 1 END) = 0
ORDER BY id;
Upvotes: 1
Reputation: 94914
This answer is no longer valid, as the OP has altered the requirement.
No, this is not complex. You want to exclude subjects for which exist HR1/2 records with a value outside the given bounds. So use NOT EXISTS
or NOT IN
.
select *
from mytable
where subject_id not in
(
select subject_id
from mytable
where event in ('HR1', 'HR2')
and event_value not between 50 and 100
)
order by subject_id;
Upvotes: 1
Reputation: 1269763
Thorsten's answer is fine, but I would express it as:
select subject_id,
min(event) -- only one event per subject
from mytable
where event in ('HR1', 'HR2')
group by subject_id
having min(event_value) >= 50 and
max(event_value) <= 110
order by subject_id;
Upvotes: 2