我想要做的是从招生表中我想知道在每个访问日期过去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;
&#13;
答案 0 :(得分:0)
没有得到你想要的东西(你说你想要的东西与Sam和Victor不匹配 - Sam的第2行是彼此在30天之内的唯一一行,并且这意味着在另一个之后的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
这将使所有在访问后30天内有一次或多次访问的患者(或基本上在30天内访问2次)
如果您想添加更多条件(例如患者最后一次访问后30天内,或2次或更多次等),您应该可以非常轻松地添加其他条件。
SQL小提琴 - http://sqlfiddle.com/#!6/4831e/13