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

按年份区间、专科及地区统计客户总数的SQL查询需求

问题描述

我有一个存储客户信息的customers表,表结构及示例数据如下:

iddateInscriptionspecialitedept
12018-04-09Anesthesiology75
22004-02-16Neurology62
31999-01-01Pathology34
42016-05-13Family medicine59

我需要按年份区间、specialite(专科)、dept(地区)统计客户总数。目前已实现按单一年份统计的SQL查询如下:

SELECT
    YEAR(dateInscription) as 'Annee_inscription',
    a.specialite,
    a.dept as 'Departement',
    COUNT(a.id) as 'NOMBRE_PS'
FROM
    customers a
WHERE
    YEAR(dateInscription) IN(2013,
    2015,
    2017,
    2019,
    2021)
    AND a.specialite IN ('ANATOMIE ET CYTOLOGIE PATHOLOGIQUES',
    'ANESTHESIE-REANIMATION',
    'BIOLOGIE MEDICALE',
    'CARDIOLOGIE/PATHOLOGIE CARDIO-VASCULAIRE')
GROUP BY
    Annee_inscription,
    a.specialite ,
    Departement
ORDER BY
    Annee_inscription ASC,
    a.specialite ASC,
    Departement ASC

期望的输出格式如下:

Year_rangespecialitedeptnumber_customer
1999-2004Anesthesiology0110
1999-2004Anesthesiology0213
1999-2004Anesthesiology0325
.............
1999-2004Family medicine01124
1999-2004Family medicine02514
1999-2004Family medicine031284
.............
1999-2006Anesthesiology0115
1999-2006Anesthesiology0217
1999-2006Anesthesiology0329
.............

我尝试过用CASE语句分组但没得到理想结果,且没有该数据库的写入权限,求可行的解决方案。

解决方案

方法1:使用CASE语句定义固定年份区间

如果你的年份区间是固定的(比如示例中的1999-2004、1999-2006等),可以直接用CASE把每个客户的注册年份映射到对应的区间,再分组统计:

SELECT
    CASE
        WHEN YEAR(dateInscription) BETWEEN 1999 AND 2004 THEN '1999-2004'
        WHEN YEAR(dateInscription) BETWEEN 1999 AND 2006 THEN '1999-2006'
        -- 可根据需求添加更多区间
        ELSE '其他'
    END AS Year_range,
    specialite,
    LPAD(dept, 2, '0') AS dept, -- 补零格式化地区编码,根据数据库调整函数
    COUNT(id) AS number_customer
FROM customers
-- 保留需要的专科筛选条件
WHERE specialite IN ('ANATOMIE ET CYTOLOGIE PATHOLOGIQUES', 'ANESTHESIE-REANIMATION', 'BIOLOGIE MEDICALE', 'CARDIOLOGIE/PATHOLOGIE CARDIO-VASCULAIRE')
GROUP BY Year_range, specialite, dept
ORDER BY Year_range, specialite, dept;

注意:如果同一个年份属于多个区间(比如2004同时属于1999-2004和1999-2006),该方法会让对应客户被统计到多个区间中,符合你期望的重复统计逻辑。

方法2:用CTE生成年份区间列表(适合动态区间)

如果需要更灵活的区间定义,可通过CTE(公共表表达式)生成所有需要统计的区间,再关联原表统计:

WITH year_ranges AS (
    SELECT '1999-2004' AS Year_range, 1999 AS start_year, 2004 AS end_year
    UNION ALL
    SELECT '1999-2006' AS Year_range, 1999 AS start_year, 2006 AS end_year
    -- 添加更多区间
)
SELECT
    yr.Year_range,
    c.specialite,
    LPAD(c.dept, 2, '0') AS dept, -- 补零格式化地区编码
    COUNT(c.id) AS number_customer
FROM year_ranges yr
LEFT JOIN customers c ON YEAR(c.dateInscription) BETWEEN yr.start_year AND yr.end_year
WHERE c.specialite IN ('ANATOMIE ET CYTOLOGIE PATHOLOGIQUES', 'ANESTHESIE-REANIMATION', 'BIOLOGIE MEDICALE', 'CARDIOLOGIE/PATHOLOGIE CARDIO-VASCULAIRE')
GROUP BY yr.Year_range, c.specialite, c.dept
ORDER BY yr.Year_range, c.specialite, c.dept;

这种方法的优势是区间定义集中在CTE里,修改起来更方便,且同样能实现同一客户在多个区间被统计的效果。

地区编码补零函数说明

不同数据库的补零函数略有差异,可根据实际情况替换:

  • MySQL/MariaDB:LPAD(dept, 2, '0')
  • PostgreSQL:LPAD(dept::text, 2, '0')
  • SQL Server:RIGHT('00' + CAST(dept AS VARCHAR(2)), 2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:54:23