SQL 问题 - 如何在 SQL 服务器中使用迭代日期逻辑输出
SQL question - how to output using iterative date logic in SQL Server
我有以下示例 table(为简单起见提供了单个 ID - 需要对所有 ID 执行相同的逻辑)
ID Visit_date
-----------------
ABC 8/7/2019
ABC 9/10/2019
ABC 9/12/2019
ABC 10/1/2019
ABC 10/1/2019
ABC 10/8/2019
ABC 10/15/2019
ABC 10/17/2019
ABC 10/24/2019
这是我需要的示例输出
在“new_visit”列中将第一次访问标记为 1
将后续日期与第一个日期进行比较,直到超过 21 天条件。示例 9 月 10 日与 8 月 7 日相比,它不在 8 月 7 日的 21 天内,因此这被视为另一个 new_visit,因此将 new_visit 标记为 1
然后我们将 9 月 10 日与随后的日期与 21 天标准进行比较,并将它们全部标记为 9 月 10 日访问的 follow_up。例如。 9月12日、10月1日为9月10日后21天内;因此它们被视为后续访问,因此将“follow_up”标记为 1
如果后续日期超过上次新访问的 21 天标准(例如,10 月 8 日与 9 月 10 日相比),则 10 月 8 日将被视为新访问并标记“New_visit”作为 1 和后续日期将与 10 月 8 日进行比较
示例输出:
Dates New_Visit Follow_up
-----------------------------
8/7/2019 1
9/10/2019 1
9/12/2019 1
10/1/2019 1
10/1/2019 1
10/8/2019 1
10/15/2019 1
10/17/2019 1
10/24/2019 1
您需要一个递归 CTE 来处理这个问题。这是想法,尽管确切的语法可能因数据库而异:
with recursive t as (
select id, date,
row_number() over (partition by id order by date) as seqnum
from yourtable
),
recursive cte as (
select id, date, visit_start as date, 1 as is_new_visit
from t
where id = 1
union all
select cte.id, t.date,
(case when t.date < visit_start + interval '21 day'
then cte.visit_start else t.date
end) as visit_start,
(case when t.date < cte.visit_start + interval '21 say'
then 0 else 1
end) as is_new_visit
from cte join
t
on t.id = cte.id and t.seqnum = cte.seqnum + 1
)
select *
from cte
where is_new_visit = 1;
您需要对此进行递归查询。
您将枚举行,然后按日期升序遍历数据集,同时跟踪每个组的首次访问日期;当距离上次首次访问的时间间隔超过 21 天时,首次访问的日期将重置,并开始新的组。
with
data as (
select t.*, row_number() over(partition by id order by date) rn
from mtytable t
),
cte as (
select id, visit_date, visit_date first_visit_date
from data
where rn = 1
union all
select c.id, d.visit_date, case when d.visit_date > datead(day, 21, c.first_visit_date) then d.visit_date else c.first_visit_date end
from cte c
inner join data d on d.id = c.id and d.rn = c.rn + 1
)
select
id,
date,
case when visit_date = first_visit_date then 1 else 0 end as is_new
case when visit_date = first_visit_date then 0 else 1 end as is_follow_up
from cte
如果一个病人可能有超过 100 次就诊,那么您需要在查询的最后添加 option (maxrecursion 0)
。
我有以下示例 table(为简单起见提供了单个 ID - 需要对所有 ID 执行相同的逻辑)
ID Visit_date
-----------------
ABC 8/7/2019
ABC 9/10/2019
ABC 9/12/2019
ABC 10/1/2019
ABC 10/1/2019
ABC 10/8/2019
ABC 10/15/2019
ABC 10/17/2019
ABC 10/24/2019
这是我需要的示例输出
在“new_visit”列中将第一次访问标记为 1
将后续日期与第一个日期进行比较,直到超过 21 天条件。示例 9 月 10 日与 8 月 7 日相比,它不在 8 月 7 日的 21 天内,因此这被视为另一个 new_visit,因此将 new_visit 标记为 1
然后我们将 9 月 10 日与随后的日期与 21 天标准进行比较,并将它们全部标记为 9 月 10 日访问的 follow_up。例如。 9月12日、10月1日为9月10日后21天内;因此它们被视为后续访问,因此将“follow_up”标记为 1
如果后续日期超过上次新访问的 21 天标准(例如,10 月 8 日与 9 月 10 日相比),则 10 月 8 日将被视为新访问并标记“New_visit”作为 1 和后续日期将与 10 月 8 日进行比较
示例输出:
Dates New_Visit Follow_up
-----------------------------
8/7/2019 1
9/10/2019 1
9/12/2019 1
10/1/2019 1
10/1/2019 1
10/8/2019 1
10/15/2019 1
10/17/2019 1
10/24/2019 1
您需要一个递归 CTE 来处理这个问题。这是想法,尽管确切的语法可能因数据库而异:
with recursive t as (
select id, date,
row_number() over (partition by id order by date) as seqnum
from yourtable
),
recursive cte as (
select id, date, visit_start as date, 1 as is_new_visit
from t
where id = 1
union all
select cte.id, t.date,
(case when t.date < visit_start + interval '21 day'
then cte.visit_start else t.date
end) as visit_start,
(case when t.date < cte.visit_start + interval '21 say'
then 0 else 1
end) as is_new_visit
from cte join
t
on t.id = cte.id and t.seqnum = cte.seqnum + 1
)
select *
from cte
where is_new_visit = 1;
您需要对此进行递归查询。
您将枚举行,然后按日期升序遍历数据集,同时跟踪每个组的首次访问日期;当距离上次首次访问的时间间隔超过 21 天时,首次访问的日期将重置,并开始新的组。
with
data as (
select t.*, row_number() over(partition by id order by date) rn
from mtytable t
),
cte as (
select id, visit_date, visit_date first_visit_date
from data
where rn = 1
union all
select c.id, d.visit_date, case when d.visit_date > datead(day, 21, c.first_visit_date) then d.visit_date else c.first_visit_date end
from cte c
inner join data d on d.id = c.id and d.rn = c.rn + 1
)
select
id,
date,
case when visit_date = first_visit_date then 1 else 0 end as is_new
case when visit_date = first_visit_date then 0 else 1 end as is_follow_up
from cte
如果一个病人可能有超过 100 次就诊,那么您需要在查询的最后添加 option (maxrecursion 0)
。