You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL实现累计求和与累计计数 统计患者治疗疗程

治疗疗程划分逻辑的SQL实现方案

背景

我正在搭建患者治疗疗程划分规则,目前已经通过Python完成计算输出,需要将同等逻辑迁移到SQL环境实现。

样例数据

PatientIDSessionDateNext_datediffcoursesCoursenumcourse_CountTotal Session
1000012/13/2012NULL1.1start1110
1000012/14/201212/13/20121existing1210
1000012/14/201212/14/20120existing1310
1000012/17/201212/14/20123existing1410
1000012/18/201212/17/20121existing1510
1000012/19/201212/18/20121existing1610
1000012/21/201212/19/20122existing1710
1000012/21/201212/21/20120existing1810
1000012/22/201212/21/20121existing1910
1000012/24/201212/22/20122existing11010
100009/17/20151/25/2013965start2120
100009/18/20159/17/20151existing2220
100009/21/20159/18/20153existing2320
100009/22/20159/21/20151existing2420
100009/23/20159/22/20151existing2520
100009/25/20159/23/20152existing2620
100009/28/20159/25/20153existing2720
100009/29/20159/28/20151existing2820
100009/30/20159/29/20151existing2920
1000010/2/20159/30/20152existing21020
1000010/5/201510/2/20153existing21120
1000010/6/201510/5/20151existing21220
1000010/7/201510/6/20151existing21320
1000010/9/201510/7/20152existing21420
1000010/12/201510/9/20153existing21520
1000010/13/201510/12/20151existing21620
1000010/14/201510/13/20151existing21720
1000010/16/201510/14/20152existing21820
1000010/19/201510/16/20153existing21920
1000010/20/201510/19/20151existing22020

*说明:diff列中的1.1是NULL值的占位符,无实际业务含义。

现有Python实现逻辑

实现代码如下:

sessions['Coursenum']=(sessions.courses.eq('start')).cumsum()
sessions['course_count']=sessions.groupby(['Coursenum']).cumcount()+1
sessions['TotalSessions']=sessions.groupby('Coursenum')['course_count'].transform('max')

核心计算逻辑:

  • 识别courses列值为start的疗程起始记录,通过累计求和生成疗程编号Coursenum
  • 按Coursenum分组,对组内记录按顺序累计计数,生成单疗程内的会话序号course_Count
  • 按Coursenum分组取组内会话序号最大值,得到单疗程总会话数Total Session

SQL实现方案

基于标准ANSI窗口函数编写,兼容MySQL 8.0+、PostgreSQL、SQL Server、BigQuery等支持窗口函数的数据库引擎:

WITH step1 AS (
    SELECT
        *,
        -- 对齐Python cumsum逻辑,累计start标记生成疗程编号
        SUM(CASE WHEN courses = 'start' THEN 1 ELSE 0 END) OVER (
            ORDER BY PatientID, SessionDate
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS Coursenum
    FROM sessions
),
step2 AS (
    SELECT
        *,
        -- 对齐分组cumcount+1逻辑,生成疗程内会话序号
        ROW_NUMBER() OVER (
            PARTITION BY PatientID, Coursenum
            ORDER BY SessionDate
        ) AS course_Count
    FROM step1
)
SELECT
    *,
    -- 对齐分组取max逻辑,计算单疗程总会话数
    MAX(course_Count) OVER (PARTITION BY PatientID, Coursenum) AS `Total Session`
FROM step2;

注意事项

  • 涉及多患者数据时,所有窗口计算必须携带PatientID作为分区字段,避免跨患者数据串算
  • 若同一患者同一天存在多条就诊记录,建议在窗口的ORDER BY子句中补充唯一排序字段(如就诊记录自增ID、精确到时分秒的就诊时间),保证记录排序和Python处理时的顺序完全一致,避免序号错位

内容的提问来源于stack exchange,提问作者PKN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 17:33:39