首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL仅在眼镜蛇感染时选择药物。

SQL仅在眼镜蛇感染时选择药物。
EN

Stack Overflow用户
提问于 2020-06-18 21:45:41
回答 3查看 125关注 0票数 0

我有两张桌子。表'lab_obs‘记录的结果时,病人被测试的贪心。表中的“药物”记录了所有患者服用的所有药物(无论测试与否)。以下是简化的模式:

代码语言:javascript
复制
CREATE TABLE lab_obs (ob_day DATE, 
                          ob VARCHAR(20),
                          patient_id VARCHAR(20)
                         );

CREATE TABLE medications (given_day DATE, 
                          med VARCHAR(20),
                          patient_id VARCHAR(20)
                         );                         

INSERT INTO lab_obs VALUES ('2020-03-01', 'positive', 'p11');
INSERT INTO lab_obs VALUES ('2020-05-01', 'negative', 'p11');
INSERT INTO lab_obs VALUES ('2020-03-02', 'negative', 'p12');
INSERT INTO lab_obs VALUES ('2020-06-01', 'negative', 'p11');
INSERT INTO lab_obs VALUES ('2020-06-01', 'negative', 'p12');

INSERT INTO medications VALUES ('2020-03-05', 'covid_med_11', 'p11');
INSERT INTO medications VALUES ('2020-03-05', 'non_covid_med_12', 'p12');
INSERT INTO medications VALUES ('2020-02-05', 'non_covid_med_11', 'p11');
INSERT INTO medications VALUES ('2020-04-05', 'non_covid_med_41', 'p41');

我想写一个SQL,它将给我(patient_id,med)测试阳性和随后测试阴性的病人,以及在阳性测试和随后的阴性测试之间所服用的所有药物。基本上,这个查询应该给我从Covid康复的病人服用的所有药物!!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-18 21:58:59

我想这就是你想要的。使用延迟函数检查以前的记录。我在SQL server中运行了它。此外,请使用代码进行观察,因为拼写可能导致问题,例如,积极而不是积极。

代码语言:javascript
复制
SELECT m.patient_id, m.med , m.given_day
FROM medications m
JOIN (SELECT patient_id, 
       CASE WHEN ob = 'negative'
             AND lag(ob) OVER (partition by patient_id order by l.ob_day) = 'postive'
            THEN 1
            ELSE 0 
            END as qualify
      FROM lab_obs l) l ON l.patient_id = m.patient_id AND l.qualify = 1
票数 1
EN

Stack Overflow用户

发布于 2020-06-18 22:05:17

尝试使用PostgreSQL (不确定您使用的是哪个关系数据库管理系统)。为此,您需要窗口函数和CTE:

代码语言:javascript
复制
WITH lagged_obs AS (
    SELECT patient_id,
           ob_day,
           ob,
           LAG(ob) OVER (PARTITION BY patient_id ORDER BY ob_day) AS lagged_ob
    FROM lab_obs
)
, patient_status_change AS (
    -- Look for status changes, useful for consecutive tests with same result
    SELECT patient_id,
           ob_day AS ob_change_day,
           ob
    FROM lagged_obs
    WHERE ob IS DISTINCT FROM lagged_ob
)
, patient_infected_periods AS (
    -- Build time periods
    SELECT patient_id,
           ob_change_day AS start_date,
           LEAD(ob_change_day)
               OVER (PARTITION BY patient_id ORDER BY ob_change_day) AS end_date,
           ob AS period_status
    FROM patient_status_change
)
SELECT pip.patient_id, m.given_day, m.med
FROM patient_infected_periods pip
    INNER JOIN medications m
    ON pip.patient_id=m.patient_id AND pip.start_date <= m.given_day AND m.given_day < pip.end_date
WHERE pip.period_status='postive'
票数 1
EN

Stack Overflow用户

发布于 2020-06-18 22:06:02

这有点棘手。如果某人只检测一次阳性,那么:

代码语言:javascript
复制
select m.*
from medications m
where m.given_day >= (select min(l.ob_day)
                      from lab_obs l
                      where l.patient_id = m.patient_id and l.ob = 'positive'
                     ) and
      m.given_day < (select min(l.ob_day)
                     from (select l.*, min(case when ob = 'positive' then ob_day end) as pos_ob_day
                           from lab_obs l
                          ) l
                     where l.patient_id = m.patient_id and
                           l.ob = 'negative' and
                           l.ob_date > pos_ob_day
                        );

这适用于消极-积极-消极和积极-消极的情况。

如果有人可以来回切换,那么我建议像这样使用lag()

代码语言:javascript
复制
select m.*, l.*
from medications m join
     (select l.*,
             lead(ob_day) over (partition by patient_id order by ob_day) as next_ob_day
      from (select l.*,
                   lag(ob) over (partition by patient_id order by ob_day) as prev_ob
           from lab_obs l
          ) l
      where prev_ob is null or prev_ob <> ob
     ) l
     on m.patient_id = l.patient_id and
        m.given_date >= l.ob_day and
        m.given_date < l.next_ob_day and
        l.ob = 'positive';

l子查询是确定何时某人第一次测试阳性,然后用不同的测试值确定下一个测试日期。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62459904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档