SQL连接:选择满足原始表中条件的最后一条记录

时间:2013-10-03 20:38:37

标签: sql

我是SQL的新手,所以请原谅任何符号。我的问题的一个简化版本如下。我在表ADMISSIONS中接受了住院治疗,需要从表CLAIMS 之前收集某种类型的最新门诊声明到入院日期:

SELECT a.ID , a.date, b.claim_date
FROM admissions as a
LEFT JOIN claims b on  (a.ID=b.ID) and (a.date>b.claim_date) 
LEFT JOIN claims c on ((a.ID=c.ID) and (a.date>c.claim_date))
     and (b.claim_date<c.claim_date or b.claim_date=c.claim_date and b.ID<c.ID)
WHERE c.ID is NULL

问题在于,对于某些ID,我会获得许多带有重复a.date,c.claim_date值的记录。

我的问题类似于此处讨论的问题

SQL join: selecting the last records in a one-to-many relationship

并详细阐述

SQL Left join: selecting the last records in a one-to-many relationship

然而,只有在a.date之前发现的CLAIMS中的记录还有额外的皱纹,我认为这会导致问题。

更新

时间不存储,只是日期,并且由于患者可以在同一天拥有多条记录,这是一个问题。还有另一个问题,那就是我只想看一下CLAIMS的一个子集(假设claim.flag = TRUE)。这是我上次尝试的内容:

SELECT a.ID , a.date, b.claim_date
FROM admissions as a
LEFT JOIN (
       select d.ID , max(d.claim_date) cdate
       from claims as d
       where d.flag=TRUE
       group by d.ID
       ) as b on  (a.ID=b.ID) and (b.claim_date < a.date) 
LEFT JOIN claims c on ((a.ID=c.ID) and (c.claim_date < a.claim_date))
     and c.flag=TRUE
     and (b.claim_date<c.claim_date or b.claim_date=c.claim_date and b.ID<c.ID)
WHERE c.ID is NULL

然而,这在流产前持续了几个小时(通常需要约30分钟,LIMIT 10)。

1 个答案:

答案 0 :(得分:1)

您可能想尝试使用子查询来解决此问题:

SELECT a.ID, a.date, b.claim_date
  FROM admissions as a
  LEFT JOIN claims b ON (a.ID = b.ID)
  WHERE b.claim_date = (
    SELECT MAX(c.claim_date) 
      FROM claims c 
      WHERE c.id = a.id -- Assuming that c.id is a foreign key to a.id
        AND c.claim_date < a.date  -- Claim date is less than admission date
  );

尝试使用不同的ID进行澄清,并使用其他子查询来计算重复日期:

SELECT a.ID, a.patient_id, a.date, b.claim_id, b.claim_date
  FROM admissions as a
  LEFT JOIN claims b ON (a.patient_ID = b.patient_ID)
  WHERE b.claim_id = (
    SELECT MAX(c.claim_id)  -- Max claim identifier (likely most recent if sequential)
      FROM claims c 
      WHERE c.patient_ID = a.patient_ID
                    AND c.flag = TRUE
                    AND c.claim_date = (
                        SELECT MAX(d.claim_date) 
                            FROM claims d
                            WHERE d.patient_id = c.patient_id 
                                AND c.claim_date < a.date  -- Claim date is less than admission date
                                AND d.flag = TRUE
                    )
  )
        b.flag = TRUE;