sql - 选择满足两个条件的ID

标签 sql postgresql

我一直在尝试从事件表中查询(下面我展示了一个具有预期输出的示例)。

这个表有3个以上的事件类型,但我只显示相关的。这些相关的 3 种类型是:“HRa1”(代码 211)、“HRa2”(代码 12712)和“HRy”(代码 220048)。 'HRa'分为'HRa1'和'HRa2',因为它们因人将它们插入 table 而异,但它们不会同时发生。

我要选择以下内容:

  • 如果只出现这 3 种类型中的一种:如果是 'HRa1' 或 'HRa2',请选择其所有 'HRa1'/'HRa2' 值(列 valuenum)都在 50 到 110 之间的那些;如果它是“HRy”,则选择所有值(列值)都等于“sinus”的那些。请参阅 ID = 1、2、3、4 和 5。可以存在其他类型的事件,这无关紧要,但只会出现上述 3 种事件之一(请参阅 ID = 3)。

  • 如果“HRa1”/“HRa2”和“HRy”都出现,则所有“HRa1”/“HRa2”条目中的“HRa1”/“HRa2”(数值)必须介于 50 和 110 之间,和“HRy”(值)条目必须全部等于“正弦”。 ID = 8 显示了不满足此条件的示例。

  • 如果这 3 个都没有出现,当然排除。

我怎样才能做到这一点?

drop table testevents cascade;
create table testevents(
hadm_id int not null,
subject_id int not null,
eventtype int not null,
eventlabel char(30) not null,
value char(360) not null,
valuenum int
);

insert into testevents(hadm_id, subject_id, eventtype, eventlabel, value, valuenum)
values
    (1, 1, 211, 'HRa1', '59', 59),
    (1, 1, 211, 'HRa1', '89', 59),
    (1, 1, 211, 'HRa1', '54', 59),
    (1, 1, 211, 'HRa1', '99', 59),
    (1, 1, 211, 'HRa1', '69', 59),
    (1, 1, 211, 'HRa1', '104', 59),

    (2, 2, 211, 'HRa1', '59', 59),
    (2, 2, 211, 'HRa1', '89', 89),
    (2, 2, 211, 'HRa1', '54', 54),
    (2, 2, 211, 'HRa1', '140', 140), -- not allowed
    (2, 2, 211, 'HRa1', '69', 69),
    (2, 2, 211, 'HRa1', '104', 104),

    (3, 3, 12712, 'HRa2', '69', 69),
    (3, 3, 12712, 'HRa2', '89', 89),
    (3, 3, 12712, 'HRa2', '94', 94),
    (3, 3, 12712, 'HRa2', '59', 59),
    (3, 3, 12712, 'HRa2', '69', 69),
    (3, 3, 12712, 'HRa2', '84', 84),
    (3, 3, 353, 'RXa', 'OK', null), 

    (4, 4, 220048, 'HRy', 'sinus', null),
    (4, 4, 220048, 'HRy', 'sinus', null),
    (4, 4, 220048, 'HRy', 'sinus', null),
    (4, 4, 220048, 'HRy', 'sinus', null),
    (4, 4, 220048, 'HRy', 'sinus', null),
    (4, 4, 220048, 'HRy', 'sinus', null),

    (5, 5, 220048, 'HRy', 'sinus', null),
    (5, 5, 220048, 'HRy', 'sinus', null),
    (5, 5, 220048, 'HRy', 'sinus', null),
    (5, 5, 220048, 'HRy', 'AF', null), -- not allowed
    (5, 5, 220048, 'HRy', 'sinus', null),
    (5, 5, 220048, 'HRy', 'sinus', null),

    (6, 6, 220048, 'HRy', 'sinus', null),
    (6, 6, 220048, 'HRy', 'sinus', null),
    (6, 6, 211, 'HRa2', '94', 95),
    (6, 6, 211, 'HRa2', '150', 150), -- not allowed
    (6, 6, 220048, 'HRy', 'sinus', null),
    (6, 6, 220048, 'HRy', 'sinus', null),

    (7, 7, 220048, 'HRy', 'sinus', null),
    (7, 7, 220048, 'HRy', 'sinus', null),
    (7, 7, 211, 'HRa2', '94', 94),
    (7, 7, 211, 'HRa2', '87', 87),
    (7, 7, 220048, 'HRy', 'sinus', null),
    (7, 7, 220048, 'HRy', 'sinus', null),
    (7, 7, 4053, 'BP', '87', 87), 
    (7, 7, 503, 'RR', '72', 72),

    (8, 8, 220048, 'HRy', 'sinus', null),
    (8, 8, 211, 'HRa2', '94', 94),
    (8, 8, 211, 'HRa2', '87', 87),
    (8, 8, 220048, 'HRy', 'AF', null), -- not allowed
    (8, 8, 220048, 'HRy', 'sinus', null),
    (8, 8, 4053, 'BP', '87', 87), 
    (8, 8, 503, 'RR', '72', 72),

    (9, 9, 220048, 'HRy', 'AF', null), -- not allowed
    (9, 9, 211, 'HRa2', '134', 134), -- not allowed
    (9, 9, 211, 'HRa2', '187', 187), -- not allowed
    (9, 9, 220048, 'HRy', 'AF', null), -- not allowed
    (9, 9, 220048, 'HRy', 'AF', null) -- not allowed
;


output:
hadm_id, subject_id
1            1
3            3
4            4
7            7

我正在尝试以下查询,但对于 ID = 8 它失败了:

select subject_id, hadm_id
from testevents
where eventlabel in ('HRa1', 'HRa2', 'HRy') 
group by subject_id, hadm_id
having ((min(valuenum) >= 50 and max(valuenum) <= 110) or
       (min(value) = 'sinus' and max(value) = 'sinus'))
order by subject_id;

有人可以帮助我吗? 非常感谢!

最佳答案

你的条件有点复杂。我认为这捕获了逻辑:

select subject_id, hadm_id
from testevents
where eventlabel in ('HRa1', 'HRa2', 'HRy') 
group by subject_id, hadm_id
having (min(eventlabel) = max(eventlabel) and
        min(eventlabel) in ('HRa1', 'HRa2') and
        min(valuenum) >= 50 and
        max(valuenum) <= 110
       ) or
       (min(eventlabel) = max(eventlabel) and
        min(eventlabel) in ('HRy') and
        min(value) = 'sinus' and
        max(value) = 'sinus'
       ) or
       (sum( (eventlabel in ('HRa1', 'HRa2'))::int) > 0 and
        sum( (eventlabel in ('HRy'))::int) > 0 and
        min(case when eventlabel in ('HRa1', 'HRa2') then valuenum end) >= 50 and
        max(case when eventlabel in ('HRa1', 'HRa2') then valuenum end) <= 110 and
        sum( (eventlabel in ('HRy') and value <> 'sinus')::int ) = 0
       ) 

Here是一个 SQL fiddle 。

关于sql - 选择满足两个条件的ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52016824/

相关文章:

sql - 如何根据最大计数选择一行? (使用标准sql)

MySQL:如何为具有接近时间戳的记录分配相同的ID

sql - Oracle:如何限制 "select .. for update skip locked"中的行数

postgresql - 将复杂的 postgresql 查询/子查询转换为 Rails 事件记录语法或将数组转换为事件记录关系?

sql - 组合 2 个查询 - 在一个查询中获取列名并在另一个查询中使用结果

sql - oracle sql和pl/sql中varchar2的区别

postgresql - 如何为 docker-compose 和 DockerFile 设置不同的上下文

postgresql - 选择直到 postgresql 中的行匹配?

postgresql - 如何在 PostgreSQL 中创建一个新函数作为另一个函数的别名?

postgresql - 如何从 PostgreSQL 存储过程返回结果集?