SQL 根据条件查询最近的值

SQL query most recent value with conditions

又一次尝试,第一次写了个坑坑洼洼的问题。我希望这会更好。

我有 2 个表 - 患者和临床参数h:

PATIENT
ID  Last    First
190 Smith   Frank
191 Smith   Flo


CLINICALPARAMETERH
SBP DBP Datetime            PatientID
124 86  2020-07-13 13:49:05 190
144 86  2020-08-13 13:49:05 190
134 96  2020-08-13 13:49:05 190
120 89  2009-07-13 13:49:05 190
132 76  2009-07-13 13:49:05 190
122 76  2020-07-13 13:49:05 191

我需要看看

ID Last First

只有在 1) SBP <140 和 2) DBP <90 和 3) 这些是去年完成的最新读数时,我才希望看到这个。

因此,如果它是 >1 年前的,或者不是最近的读数,或者 SBP > 139 或 DBP > 89,则不应进入列表。 (所以在这个例子中它会显示 Flo 的名字而不是 Frank,但是因为他最近的名字超出了范围)

如有任何帮助,我们将不胜感激,谢谢。希望我解释了我在寻找什么。

好吧,您可以使用相关子查询来获取最近的日期。剩下的就是过滤了。在标准 SQL 中,您可以这样做:

select p.*, cph.*
from patient p join
     CLINICALPARAMETERH cph
     on p.id = cph.patientid
where pch.datetime = (select max(cph2.datetime)
                      from CLINICALPARAMETERH cph2
                      where cph2.patientId = cph.patientId
                     ) and
      pch.datetime > current_date - interval '1 year' and
      pch.SBP < 140 and
      pch.DBP < 90;

Date/time 众所周知,函数依赖于数据库,因此确切的语法可能因您实际使用的数据库而异。

一个选项使用 window 函数:

select p.*, c.*
from patient p
inner join (
    select c.*,
        row_number() over(partition by patientid order by datetime desc) rn
    from clinicalparameterh c
) c on c.patientid = p.id
where 
    c.rn = 1
    and c.sbp < 140
    and c.dbp < 90
    and c.datetime > current_date - interval '1' year

日期函数因数据库而异,因此最后一个条件的拼写可能因您使用的产品而异:查询使用标准 ANSI SQL 语法。

您可以rank() 去年患者的数据按拍摄时间降序排列。然后,您可以仅过滤排名第一且具有您所追求的值的那些。存在此类记录的患者就是您想要的患者。因此,您可以使用带有 EXISTS 的相关子查询来过滤它们。

SELECT p.id,
       p.last,
       p.first
       FROM patient p
       WHERE EXISTS (SELECT *
                            FROM (SELECT cp.sbp,
                                         cp.dbp,
                                         cp.patientid,
                                         rank() OVER (PATITION BY cp.patientid
                                                      ORDER BY cp.datetime DESC) r
                                         FROM clinicalparameterh cp
                                         WHERE cp.datetime >= now - INTERVAL 1 YEAR) x
                                                           -- ^ this might vary   ^
                                                           --   depending on your
                                                           --   actual DBMS        
                            WHERE x.patentid = p.id
                                  AND x.sbp < 140
                                  AND x.dbp < 90
                                  AND x.r = 1);