分层查询调试

Hierarchial query debugging

我想做的是从入院开始 table 我想知道从每次就诊日期算起的过去 30 天内来过两次以上医院的患者的姓名。我用 CTE 提出了以下查询,理想情况下它应该只重新调整两个名称但它返回 3。我不确定我哪里出错了。

create table admissions(Patient_id int, patient_name varchar(50),   visitdate datetime);

insert into admissions (patient_id, patient_name, visitdate) values(1,  'Victor',   cast('2014-04-10 22:01:13.373' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(1,  'Victor',   cast('2014-06-14 22:01:53.923' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(1,  'Victor',   cast('2014-04-15 22:01:53.927' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(1,  'Victor',   cast('2014-04-19 22:01:53.960' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(1,  'Victor',   cast('2014-04-30 22:01:53.963' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(2,  'Sam',      cast('2014-04-25 22:04:32.547' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(2,  'Sam',      cast('2014-04-25 22:04:56.287' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(2,  'Sam',      cast('2014-06-14 22:04:56.290' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(2,  'Sam',      cast('2014-09-22 22:04:56.290' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(2,  'Sam',      cast('2015-04-05 22:04:56.290' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(3,  'Tony',     cast('2014-04-25 22:45:42.203' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(3,  'Tony',     cast('2012-10-22 22:45:42.203' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(3,  'Tony',     cast('2010-05-06 22:45:42.247' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(3,  'Tony',     cast('2001-08-01 22:45:42.247' as datetime));
insert into admissions (patient_id, patient_name, visitdate) values(3,  'Tony',     cast('2019-05-14 23:07:05.340' as datetime));

--Below query should return only two records only for (Victor and Sam)

with CTE (patient_id, patient_name, visitdate, diff, ranked) as
(
select patient_id, patient_name, visitdate, diff, ranked from
(select 
 patient_id patient_id,
 patient_name patient_name,
 visitdate visitdate, 
 cast(0 as integer) diff,
 rank() over(partition by patient_id order by visitdate desc) ranked
from admissions) a where ranked = 1

union all

select 
 test.patient_id patient_id,
 test.patient_name patient_name,
 test.visitdate visitdate,
 cast((cte.visitdate - test.visitdate)  as integer)diff,
 test.ranked ranked
from (select 
 patient_id patient_id,
 patient_name patient_name,
 visitdate visitdate, 
 rank() over(partition by patient_id order by visitdate desc) ranked
from admissions) test
inner join CTE
 on test.patient_id = CTE.patient_id
 and test.ranked = cte.ranked + 1
where (cte.visitdate - test.visitdate) <=31 
and cte.visitdate <> test.visitdate
)

select * from CTE;

没有完全得到您想要的(您所说的您想要的与 Sam 和 Victor 不匹配 - Sam 的第 1 2 行是唯一在 30 天内相隔的行,这意味着在 30 天内只有 1 次访问30 天)但试试这个

select distinct
    a.patient_id,
    a.patient_name
from admissions a 
inner join admissions b on 
    a.patient_id = b.patient_id and
    b.visitdate >= (a.visitdate - 30) and 
    b.visitdate < a.visitdate
group by 
    a.patient_id,
    a.patient_name,
    a.visitdate
having
    count(b.visitdate) >= 1

这returns所有在就诊后30天内有过1次或多次就诊的患者(或基本上30天内有2次就诊window)

如果您想添加更多条件(比如在患者上次就诊后 30 天内,或 2 天或更多天等),您应该能够很容易地添加其他条件。

SQL Fiddle - http://sqlfiddle.com/#!6/4831e/13