如何根据滚动的 30 天窗口 SQL 选择行
Posted
技术标签:
【中文标题】如何根据滚动的 30 天窗口 SQL 选择行【英文标题】:How to select rows based on a rolling 30 day window SQL 【发布时间】:2021-07-21 00:36:54 【问题描述】:我的问题涉及如何识别指数放电。
指数放电是最早的放电。在该日期,30 天窗口开始。在此期间的任何入院都被视为重新入院,应该被忽略。一旦 30 天窗口期结束,任何后续排放都将被视为一个指数,30 天窗口期将再次开始。
我似乎无法弄清楚这其中的逻辑。我尝试过不同的窗口函数,我尝试过交叉连接和交叉应用。我一直遇到的问题是重新入院不能是索引入院。它必须被排除。
我已经成功编写了一个 while 循环来解决这个问题,但如果可能的话,我真的很想以基于集合的格式来获得它。到目前为止我还没有成功。
最终目标是这个-
id | AdmitDate | DischargeDate | MedicalRecordNumber | IndexYN |
---|---|---|---|---|
1 | 2021-03-03 00:00:00.000 | 2021-03-09 13:20:00.000 | X0090362 | 1 |
4 | 2021-03-05 00:00:00.000 | 2021-03-10 16:00:00.000 | X0012614 | 1 |
6 | 2021-05-18 00:00:00.000 | 2021-05-21 22:20:00.000 | X0012614 | 1 |
7 | 2021-06-21 00:00:00.000 | 2021-07-08 13:30:00.000 | X0012614 | 1 |
8 | 2021-02-03 00:00:00.000 | 2021-02-09 17:00:00.000 | X0019655 | 1 |
10 | 2021-03-23 00:00:00.000 | 2021-03-26 16:40:00.000 | X0019655 | 1 |
11 | 2021-03-15 00:00:00.000 | 2021-03-18 15:53:00.000 | X4135958 | 1 |
13 | 2021-05-17 00:00:00.000 | 2021-05-23 14:55:00.000 | X4135958 | 1 |
15 | 2021-06-24 00:00:00.000 | 2021-07-13 15:06:00.000 | X4135958 | 1 |
示例代码如下。
CREATE TABLE #Admissions
(
[id] INT,
[AdmitDate] DATETIME,
[DischargeDateTime] DATETIME,
[UnitNumber] VARCHAR(20),
[IndexYN] INT
)
INSERT INTO #Admissions
VALUES( 1 ,'2021-03-03' ,'2021-03-09 13:20:00.000' ,'X0090362', NULL)
,(2 ,'2021-03-27' ,'2021-03-30 19:59:00.000' ,'X0090362', NULL)
,(3 ,'2021-03-31' ,'2021-04-04 05:57:00.000' ,'X0090362', NULL)
,(4 ,'2021-03-05' ,'2021-03-10 16:00:00.000' ,'X0012614', NULL)
,(5 ,'2021-03-28' ,'2021-04-16 13:55:00.000' ,'X0012614', NULL)
,(6 ,'2021-05-18' ,'2021-05-21 22:20:00.000' ,'X0012614', NULL)
,(7 ,'2021-06-21' ,'2021-07-08 13:30:00.000' ,'X0012614', NULL)
,(8 ,'2021-02-03' ,'2021-02-09 17:00:00.000' ,'X0019655', NULL)
,(9 ,'2021-02-17' ,'2021-02-22 17:25:00.000' ,'X0019655', NULL)
,(10 ,'2021-03-23' ,'2021-03-26 16:40:00.000' ,'X0019655', NULL)
,(11 ,'2021-03-15' ,'2021-03-18 15:53:00.000' ,'X4135958', NULL)
,(12 ,'2021-04-08' ,'2021-04-13 19:42:00.000' ,'X4135958', NULL)
,(13 ,'2021-05-17' ,'2021-05-23 14:55:00.000' ,'X4135958', NULL)
,(14 ,'2021-06-09' ,'2021-06-14 12:45:00.000' ,'X4135958', NULL)
,(15 ,'2021-06-24' ,'2021-07-13 15:06:00.000' ,'X4135958', NULL)
【问题讨论】:
如果您可以发布您的 while 循环代码,这将有助于理解问题。 请向我们展示您的尝试以及您遇到的问题。 【参考方案1】:您可以使用递归 CTE 来识别与每个“索引”放电相关的所有行:
with a as (
select a.*, row_number() over (order by dischargedatetime) as seqnum
from admissions a
),
cte as (
select id, admitdate, dischargedatetime, unitnumber, seqnum, dischargedatetime as index_dischargedatetime
from a
where seqnum = 1
union all
select a.id, a.admitdate, a.dischargedatetime, a.unitnumber, a.seqnum,
(case when a.dischargedatetime > dateadd(day, 30, cte.index_dischargedatetime)
then a.dischargedatetime else cte.index_dischargedatetime
end) as index_dischargedatetime
from cte join
a
on a.seqnum = cte.seqnum + 1
)
select *
from cte;
然后您可以将其合并到update
:
update admissions
set indexyn = (case when admissions.dischargedatetime = cte.index_dischargedatetime then 'Y' else 'N' end)
from cte
where cte.id = admissions.id;
Here 是一个 dbfiddle。请注意,我将IndexYN
的类型更改为分配'Y'
/'N'
的字符,考虑到列名,这很有意义。
【讨论】:
以上是关于如何根据滚动的 30 天窗口 SQL 选择行的主要内容,如果未能解决你的问题,请参考以下文章
Cypress web自动化30-操作窗口滚动条(scrollTo)