Sql 计算急诊室就诊次数,但每8天仅一次

Sql 计算急诊室就诊次数,但每8天仅一次,sql,sql-server,Sql,Sql Server,我在MS SQL Server 2017中工作,计算会员ED访问次数,会员可能会在ER访问之间停留数月,或者每次访问可能会连续多天。我试图计算的规则是: 如果会员在8天内有一次以上的教育署访问,包括 只有第一次符合条件的ED访问。例如,如果成员具有 1月1日符合条件的ED访问,包括1月1日访问,不包括 包括在1月2日至1月8日期间进行的急诊就诊。 然后,如果适用,包括在 1月9日之后。按时间顺序确定访问,仅包括 每8天一次 如果自上次访问后的天数为空或>=8,则始终计算该天数,并且我有该天数。我

我在MS SQL Server 2017中工作,计算会员ED访问次数,会员可能会在ER访问之间停留数月,或者每次访问可能会连续多天。我试图计算的规则是:

如果会员在8天内有一次以上的教育署访问,包括 只有第一次符合条件的ED访问。例如,如果成员具有 1月1日符合条件的ED访问,包括1月1日访问,不包括 包括在1月2日至1月8日期间进行的急诊就诊。 然后,如果适用,包括在 1月9日之后。按时间顺序确定访问,仅包括 每8天一次

如果自上次访问后的天数为空或>=8,则始终计算该天数,并且我有该天数。我面临的问题是如何查看自上次访问以来的运行总天数,以便在给定的8天内有多个有效访问时找到下一次有效访问

在下面的示例中,标记为绿色的行被标记为包含,因为自上次访问以来的天数为空或>=8。 黄色突出显示的行应被视为未来8天内的第一次有效就诊。粗体轮廓显示了累计达到阈值8的天数

我已经为图中的示例准备了SQL,希望有人能帮助我摆脱困境

IF OBJECT_ID('tempdb..#Example') IS NOT NULL
DROP TABLE #Example

CREATE TABLE 
    #Example (
        Subscriber_ID VARCHAR(16),
        Member_Seq VARCHAR(2),
        Measurement_Year INT,
        Visit_Date DATETIME,
    )

INSERT INTO #Example (Subscriber_ID,Member_Seq,Measurement_Year,Visit_Date) VALUES
    ('788768646','02','2019','2019-07-09'),
    ('788768646','02','2019','2019-08-05'),
    ('788768646','02','2019','2019-08-18'),
    ('788768646','02','2019','2019-09-13'),
    ('788768646','02','2019','2019-09-15'),
    ('788768646','02','2019','2019-09-19'),
    ('788768646','02','2019','2019-09-25'),
    ('788768646','02','2019','2019-10-14'),
    ('788768646','02','2019','2019-10-21'),
    ('788768646','02','2019','2019-10-24'),
    ('788768646','02','2019','2019-10-27'),
    ('788768646','02','2019','2019-10-28'),
    ('788768646','02','2019','2019-11-03'),
    ('788768646','02','2019','2019-11-06'),
    ('788768646','02','2019','2019-11-18'),
    ('788768646','02','2019','2019-12-11')

    SELECT  y.Subscriber_ID,
            y.Member_Seq,
            y.Measurement_Year,
            y.Visit_Date,
            y.Prior_Visit_Date,
            y.Days_Since_Last_Visit,
            CASE
                WHEN Days_Since_Last_Visit >= 8 OR Days_Since_Last_Visit IS NULL THEN
                    'Y'
                ELSE
                    NULL
                END Include_Visist,
            CASE 
                WHEN Days_Since_Last_Visit >= 8 OR Days_Since_Last_Visit IS NULL THEN
                    NULL
                ELSE
                    SUM (CASE 
                            WHEN Days_Since_Last_Visit >= 8 OR Days_Since_Last_Visit IS NULL THEN 
                                NULL
                            ELSE 
                                y.Days_Since_Last_Visit 
                            END
                        ) OVER (PARTITION BY y.Subscriber_ID, y.Member_Seq,y.Measurement_Year ORDER BY y.Visit_Date)
                END Running_Total
    FROM    (
            SELECT  x.Subscriber_ID,
                    x.Member_Seq,
                    x.Measurement_Year,
                    x.Visit_Date,
                    LAG(Visit_Date) OVER (
                        PARTITION BY x.Subscriber_ID, x.Member_Seq, x.Measurement_Year
                        ORDER BY x.Visit_Date) Prior_Visit_Date,
                    DATEDIFF(DAY,
                                LAG(Visit_Date) OVER (
                                    PARTITION BY x.Subscriber_ID, x.Member_Seq, x.Measurement_Year
                                    ORDER BY x.Visit_Date),
                                x.Visit_Date) Days_Since_Last_Visit
            FROM #Example x
            ) y

这是一个挑战。我添加了一些额外的测试记录,以确保它能够在几个时段内处理一长串的访问

WITH Example as (
    SELECT Subscriber_ID, Member_Seq, Measurement_Year, CAST(Visit_Date as datetime) as [Visit_Date]
    FROM (
        VALUES
            ('788768646','02','2019','2019-06-01'),
            ('788768646','02','2019','2019-06-09'),
            ('788768646','02','2019','2019-07-09'),
            ('788768646','02','2019','2019-08-05'),
            ('788768646','02','2019','2019-08-18'),
            ('788768646','02','2019','2019-09-13'),
            ('788768646','02','2019','2019-09-15'),
            ('788768646','02','2019','2019-09-19'),
            ('788768646','02','2019','2019-09-25'),
            ('788768646','02','2019','2019-10-14'),
            ('788768646','02','2019','2019-10-21'),
            ('788768646','02','2019','2019-10-24'),
            ('788768646','02','2019','2019-10-27'),
            ('788768646','02','2019','2019-10-28'),
            ('788768646','02','2019','2019-11-03'),
            ('788768646','02','2019','2019-11-06'),
            ('788768646','02','2019','2019-11-18'),
            ('788768646','02','2019','2019-12-11'),
            ('788768646','02','2020','2020-01-01'),
            ('788768646','02','2020','2020-01-08'),
            ('788768646','02','2020','2020-01-09'),
            ('788768646','02','2020','2020-01-16'),
            ('788768646','02','2020','2020-01-17'),
            ('788768646','02','2020','2020-01-24'),
            ('788768646','02','2020','2020-01-25'),

            ('788768699','02','2019','2019-06-06'),
            ('788768699','02','2019','2019-06-07'),
            ('788768699','02','2019','2019-07-17'),
            ('788768699','02','2019','2019-08-23')

        ) t (Subscriber_ID, Member_Seq, Measurement_Year, Visit_Date)
), AllVisits as (
    SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY Subscriber_ID ORDER BY Visit_Date) as [VisitSeq]
    FROM Example
), Report as (
    SELECT *, Visit_Date as [PeriodStart]
    FROM AllVisits
    WHERE VisitSeq = 1
    UNION ALL 
    SELECT a.*, 
        -- if not in the prior period, start a new 8 day period
        CASE WHEN a.Visit_Date > r.PeriodStart + 7 THEN a.Visit_Date ELSE r.PeriodStart END
    FROM AllVisits a
    INNER JOIN Report r
    ON r.Subscriber_ID = a.Subscriber_ID AND r.[VisitSeq] + 1 = a.[VisitSeq]
)
select *, 
    PeriodStart + 7 AS [PeriodEnD],
    CASE WHEN Visit_Date = PeriodStart THEN 1 ELSE 0 END as [IsFirstDayOfPeriod]
from Report 
where Visit_Date = PeriodStart
order by Subscriber_ID, Visit_Date
下面的查询获得了大多数所需的记录,但不是全部。这是它错过了一长串密切访问的地方。我想从这里开始,但我不能在CTE的递归部分使用子查询或GROUPBY。我必须做类似上面的事情,但是锚需要序列开始和结束。然后,每个锚记录的递归将在其范围内。也许有一天我会试试

    SELECT *
    FROM Example e
    WHERE NOT EXISTS( -- those with no prior within 8 days
        SELECT * 
        FROM Example x 
        WHERE x.Subscriber_ID = e.Subscriber_ID 
            AND x.Visit_Date < e.Visit_Date -- prior
            AND x.Visit_Date > e.Visit_Date - 8 -- within 8 days
        )

请为您的数据库方言添加一个标记,因为这通常会决定如何生成答案。我怀疑这可能需要一个递归查询。使用正确的标记更新,并清理示例代码。非常感谢。