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

SQL JOIN后如何准确计算month_joined计数并保留预约信息?

解决患者加入统计与预约信息关联的问题

问题背景

现有两张业务表:

Patients表

ID   | month_joined
--------------------
A110 | jan 2013 
A111 | feb 2013
A112 | april 2013

Appointments表

ID   | month_of_appt | number_of_appts
--------------------------------------
A110 | jan 2013      |       2
A110 | feb 2013      |       1
A111 | april 2013    |       3
A112 | dec 2013      |       1

需求为:统计每月新增患者数(基于Patients表month_joined字段计数),同时获取每月预约数据(可选择月度汇总或单条预约明细)。直接使用LEFT JOIN会出现问题:存在多条预约记录的患者,其month_joined字段会重复出现,导致统计该字段的计数结果偏大(比如A110的jan 2013会被统计两次,但实际该月份仅新增1位患者)。

解决方案

方案1:按月份聚合后关联(获取月度汇总数据)

先分别对两张表做月度聚合,再关联所有有数据的月份(用FULL JOIN避免遗漏任何有数据的月份):

-- 统计每月新增患者数
WITH monthly_patients AS (
    SELECT month_joined AS month, COUNT(*) AS new_patients
    FROM Patients
    GROUP BY month_joined
),
-- 统计每月预约总数
monthly_appointments AS (
    SELECT month_of_appt AS month, SUM(number_of_appts) AS total_appointments
    FROM Appointments
    GROUP BY month_of_appt
)
-- 关联两个统计结果,补全缺失值
SELECT 
    COALESCE(p.month, a.month) AS month,
    COALESCE(p.new_patients, 0) AS new_patients,
    COALESCE(a.total_appointments, 0) AS total_appointments
FROM monthly_patients p
FULL JOIN monthly_appointments a ON p.month = a.month
ORDER BY STR_TO_DATE(COALESCE(p.month, a.month), '%b %Y'); -- 按日期排序,不同数据库函数可能不同,比如PostgreSQL用TO_DATE

该方案输出每个月份的新增患者数和预约总数,例如jan 2013对应1位新增患者、2次预约;feb 2013对应1位新增患者、1次预约。

方案2:保留单条预约记录,同时显示对应加入月份的新增数

如果需要保留每条预约的详细信息,同时显示该患者加入月份的总新增患者数,可采用以下两种方式:

方法A:子查询实现

SELECT 
    a.ID,
    p.month_joined,
    a.month_of_appt,
    a.number_of_appts,
    -- 子查询获取该加入月份的新增患者总数
    (SELECT COUNT(*) FROM Patients WHERE month_joined = p.month_joined) AS new_patients_in_join_month
FROM Appointments a
LEFT JOIN Patients p ON a.ID = p.ID;

方法B:窗口函数实现(更高效)

WITH patient_join_stats AS (
    SELECT 
        ID,
        month_joined,
        -- 按month_joined分组统计新增患者数
        COUNT(*) OVER (PARTITION BY month_joined) AS new_patients_in_join_month
    FROM Patients
)
SELECT 
    a.ID,
    p.month_joined,
    a.month_of_appt,
    a.number_of_appts,
    p.new_patients_in_join_month
FROM Appointments a
LEFT JOIN patient_join_stats p ON a.ID = p.ID;

该方案会保留每条预约记录,同时正确显示对应患者加入月份的新增患者数,例如A110的两条预约记录中,new_patients_in_join_month都会显示1(因为jan 2013仅新增1位患者)。

关键说明

直接LEFT JOIN导致统计失真的核心原因是:关联后单条患者记录会被其所有预约记录复制,此时直接统计month_joined的COUNT会把重复行算入。通过先聚合患者数据,或用窗口函数在原始患者表中预计算分组统计数,即可避免重复统计的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:35:20