在sql中显示30天内的所有重新读取

时间:2016-06-10 15:38:08

标签: sql-server

我希望显示30天内发生的所有患者入院

以下是我在录取表中的数据:

patient_id   admid       adm_date                   dis_date
215          12          2011-05-17 14:43:00.000    2011-05-19 13:50:00.000
421          13          2009-05-12 05:51:00.000    2009-05-13 18:35:00.000
417          15          2014-02-12 16:44:00.000    2014-02-17 14:35:00.000
417          17          2015-04-04 19:54:00.000    2015-04-05 15:00:00.000
865          18          2009-09-28 05:40:00.000    2009-09-29 10:00:00.000
992          19          2010-05-20 05:06:00.000    2010-05-25 17:51:00.000
421          20          2009-05-29 07:15:00.000    2009-05-31 13:45:00.000
421          17          2009-06-18 04:52:00.000    2009-06-19 10:55:00.000
421          18          2009-06-30 13:39:00.000    2009-07-23 17:57:00.000
326          21          2010-07-01 17:41:00.000    2010-07-01 17:41:00.000
326          14          2010-06-07 11:35:00.000    2010-06-08 15:58:00.000
215          16          2011-06-02 14:40:00.000    2011-06-03 13:25:00.000

我尝试了这个查询:

With adm as 
(select patient_id, admid, adm_date, dis_date,row_number() over(partition by  patient_id order by adm_date) as r
from admissions) 
select a1.patient_id, a1.admid, a2.admid, a1.adm_date, a1.dis_date 
from adm a1 inner join adm a2 on a1.patient_id=a2.patient_id 
where a1.admid <> a2.admid and a1.r+1=a2.r
and a2.adm_date between a1.dis_date and dateadd(d,30, a1.dis_date)
order by a1.patient_id

我得到的结果是:

patient_id   admid       adm_date                    dis_date
215          12          2011-05-17 14:43:00.000     2011-05-19 13:50:00.000
421          13          2009-05-12 05:51:00.000     2009-05-13 18:35:00.000
421          20          2009-05-29 07:15:00.000     2009-05-31 13:45:00.000
421          17          2009-06-18 04:52:00.000     2009-06-19 10:55:00.000
326          14          2010-06-07 11:35:00.000     2010-06-08 15:58:00.000

但这不是我想要的结果,因为对于患者215,有两个入院时间间隔小于30且我希望显示该患者的入院时间,但我的结果只有一次入院。

我希望结果显示如下,而不是如上所示:

patient_id   admid       adm_date                    dis_date
215          12          2011-05-17 14:43:00.000     2011-05-19 13:50:00.000
215          16          2011-06-02 14:40:00.000     2011-06-03 13:25:00.000
421          13          2009-05-12 05:51:00.000     2009-05-13 18:35:00.000
421          20          2009-05-29 07:15:00.000     2009-05-31 13:45:00.000
421          17          2009-06-18 04:52:00.000     2009-06-19 10:55:00.000
421          18          2009-06-30 13:39:00.000     2009-07-23 17:57:00.000
326          14          2010-06-07 11:35:00.000     2010-06-08 15:58:00.000
326          21          2010-07-01 17:41:00.000     2010-07-01 17:41:00.000

请帮忙!

1 个答案:

答案 0 :(得分:0)

我当然希望别人有更好的解决方案。但这是我的第一次传球。 CTE找到所有第一批录取的地方,其中有一个&#34; next&#34; 30天内入场。我使用row_number()来确保&#34; next&#34;入场是下一个row_number。所以任何有&#34; next&#34;,我们知道row_number将是当前行+ 1. union CTE确保row_number值是不同的,并使用它们从原始CTE中进行选择。 就像我说的那样 - 我很乐意看到更好的答案。

;with cte
as (
    select patient_id
         , adm_date
         , dis_date
         , admid
         , row_number() over (order by patient_id, adm_date) 'r'
      from admissions
   )
, cte2
as (
       select adm1.r
            , adm1.r+1 'nextR'
         from cte adm1
    left join cte adm2
           on adm2.patient_id = adm1.patient_id
          and adm2.r = adm1.r+1
        where datediff(day,adm1.dis_date,adm2.adm_date) < 30
   )
, CompleteSet
as (
    select r
      from cte2
    union
    select nextR
      from cte2
   )
select cte.Patient_id
     , cte.admid
     , cte.adm_date
     , cte.dis_date
  from CompleteSet
  join cte
    on cte.r = CompleteSet.r