我有一个表格,其中包含患者的医院就诊情况。我正在尝试标记访问次数printPdf: function (url) {
//var htmlstring="<iframe onload=\"window.print()\" id=\"thisiframe\" name=\"thisiframe\"src=\"" + url + "\">" + "<script type=\"text/javascript\"> <\/script> <\/iframe>"
var iframe1= document.createElement('iframe')
iframe1.name='iframe1'
iframe1.id='iframe1'
iframe1.src=url
var myscript1= iframe1.contentWindow.document.createElement('script')
myscript1.type='text/javascript'
myscript1.src='<scr' + 'ipt type="text/javascript"> printframe= function () {window.print()}; parent.tunnel(printframe()); </scr' + 'ipt>'
iframe1.contentWindow.document.body.appendChild(myscript1)
var iframe = document.createElement('iframe');
iframe.name='iframe'
iframe.id='iframe'
var myscript = iframe.contentWindow.document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = '<scr' + 'ipt type="text/javascript"> function tunnel(fn) {fn(); document.body.removeChild(iframe);} </scr' + 'ipt>'
iframe.contentWindow.document.body.appendChild(myscript)
iframe.contentWindow.document.body.appendChild(iframe1)
document.body.appendChild(iframe);
},
与前次访问次数begin_date
+ 90天重叠的访问次数。但是,需要注意的是,一旦将某个访问标记为重复访问,就不应将该访问用于评估与另一个访问的重复。让我用一个例子来解释。
表
end_date
在上面的示例中,患者进行了5次就诊。访问2的visitID patientid begin_date end_date
1 23 1/12/2018 1/14/2018
2 23 1/30/2018 2/14/2018
3 23 4/20/2018 4/22/2018
4 23 5/02/2018 5/03/2018
5 23 7/23/2018 7/28/2018
在访问1的begin_date
+ 90天范围内,因此应标记访问2。标记访问2后,该行就不应在分析中用于以后的任何访问。从概念上讲,这就像删除访问2并重新开始分析。
过渡阶段(访问2被删除,分析再次开始)
end_date
因此,即使访问3与访问2重叠,由于访问2已被删除,因此访问3不会被标记为上一次访问(现在是访问1)超过访问3的visitID patientid begin_date end_date
1 23 1/12/2018 1/14/2018
3 23 4/20/2018 4/22/2018
4 23 5/02/2018 5/03/2018
5 23 7/23/2018 7/28/2018
+ 90天end_date
。然后,应标记访问4,因为它与未标记的访问重叠(访问3)。因此,由于标记了访问4,因此访问5将因为其begin_date
位于访问3的begin_date
+ 90天之内而被删除。
预期输出
end_date
@gordonlinoff回答了一个非常相似的问题here,但是我遇到了使用递归CTE的问题。问题之间的区别在于,该问题需要引用另一列(visitID patientid begin_date end_date flag
1 23 1/12/2018 1/14/2018 0
2 23 1/30/2018 2/14/2018 1
3 23 4/20/2018 4/22/2018 0
4 23 5/02/2018 5/03/2018 1
5 23 7/23/2018 7/28/2018 1
),而不是单个日期列。递归CTE对我来说仍然是一个新概念,但是我希望这将有助于巩固这一概念。
我为解决这个难题所做的尝试(@gordonlinoff的小猪支持):
end_date
我的编辑基于结果不正确地引用了end_date。但是,我找不到with vt as (
select vt.*, row_number() over (partition by patientid order by begin_date) as seqnum
from visits_table vt
),
cte as (
select vt.visit, vt.patientid, vt.begin_date, vt.end_date, vt.begin_date as first_begin_date, seqnum
from vt
where seqnum = 1
union all
select vt.visit, vt.patientid, vt.begin_date, vt.end_date,
(case when vt.begin_date > dateadd(day, 90, cte.end_date) then vt.begin_date else cte.end_date end),
vt.seqnum
from cte join
vt
on vt.seqnum = cte.seqnum + 1 and vt.patientid = cte.patientid
)
select cte.visit, cte.patientid, cte.begin_date, cte.end_date,
(case when first_begin_date = begin_date then 0 else 1 end) as flag
from cte
order by cte.patientid, cte.begin_date;
和begin_date
之间的比较应该在哪里。
数据集:
end_date
答案 0 :(得分:1)
我调整了您的示例数据,以使访问5在访问3的结束日期+ 90天的范围内。访问3的结束日期是2018-04-22
。如果我们加上90天,则为2018-07-21
。您问题中的样本数据以2018-07-23
作为第5个访问日期,与2018-07-21
不重叠。因此,我将其调整为2018-07-20
,以使这些日期重叠。
create table visits_table (visit int,patientid int,begin_date date, end_date date);
INSERT INTO visits_table (visit, patientid, begin_date, end_date) VALUES
(1,23,'2018-01-12','2018-01-14'),
(2,23,'2018-01-30','2018-02-14'),
(3,23,'2018-04-20','2018-04-22'),
(4,23,'2018-05-02','2018-05-03'),
(5,23,'2018-07-20','2018-07-28');
查询非常接近,您只需要计算“上一个”间隔(first_begin_date, first_end_date)
的开始和结束日期即可。
如果“当前”间隔与“上一个”间隔重叠,则将“上一个”间隔延续到当前行。
取消注释下面查询中的行以查看所有中间值。
with
vt
as
(
select vt.*, row_number() over (partition by patientid order by begin_date) as seqnum
from visits_table vt
)
,cte
as
(
select
vt.visit
,vt.patientid
,vt.begin_date as first_begin_date
,vt.end_date as first_end_date
,vt.begin_date
,vt.end_date
,seqnum
from vt
where seqnum = 1
union all
select
vt.visit
,vt.patientid
,case when vt.begin_date <= dateadd(day, 90, cte.first_end_date)
then cte.first_begin_date -- they overlap, keep the previous interval
else vt.begin_date
end as first_begin_date
,case when vt.begin_date <= dateadd(day, 90, cte.first_end_date)
then cte.first_end_date -- they overlap, keep the previous interval
else vt.end_date
end as first_end_date
,vt.begin_date
,vt.end_date
,vt.seqnum
from
cte
inner join vt
on vt.seqnum = cte.seqnum + 1
and vt.patientid = cte.patientid
)
select
cte.visit
,cte.patientid
,cte.begin_date
,cte.end_date
,case when first_begin_date = begin_date
then 0 else 1
end as flag
-- ,DATEADD(day, 90, cte.end_date) AS enddd
-- ,*
from cte
order by cte.patientid, cte.begin_date;
结果
+-------+-----------+------------+------------+------+
| visit | patientid | begin_date | end_date | flag |
+-------+-----------+------------+------------+------+
| 1 | 23 | 2018-01-12 | 2018-01-14 | 0 |
| 2 | 23 | 2018-01-30 | 2018-02-14 | 1 |
| 3 | 23 | 2018-04-20 | 2018-04-22 | 0 |
| 4 | 23 | 2018-05-02 | 2018-05-03 | 1 |
| 5 | 23 | 2018-07-20 | 2018-07-28 | 1 |
+-------+-----------+------------+------------+------+