分层查询调试
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
我想做的是从入院开始 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