如何使用SQL统计区间内数值出现次数?附降雨量统计场景
如何用SQL统计降雨量各区间的天数?
Hey,这个需求其实挺常见的,核心就是把数值映射到指定区间,再按区间分组统计。我给你两种常用的实现方案,适配不同的场景:
方案一:固定区间(适合区间不会变动的场景)
如果你的目标表区间是固定的(比如就那几个雨量段),直接用CASE WHEN把每个降雨量值映射到对应的区间标签,再分组统计就行。
假设你的源表结构:
假设源表叫daily_rainfall,字段如下:
city:城市名称(比如'北京')record_date:记录日期(DATE类型)rainfall:当日降雨量(数值类型,单位:毫米)
完整SQL示例:
SELECT CASE -- 先处理异常数据:比如负数(可能是录入错误) WHEN rainfall < 0 THEN '异常值' -- 按你的目标表区间定义写对应条件,注意边界值要和目标表一致! WHEN rainfall BETWEEN 0 AND 10 THEN '0-10mm' WHEN rainfall > 10 AND rainfall <= 20 THEN '10-20mm' WHEN rainfall > 20 AND rainfall <= 50 THEN '20-50mm' WHEN rainfall > 50 THEN '50mm及以上' -- 处理无降雨量记录的情况 ELSE '无记录' END AS rainfall_range, -- 统计天数:用record_date更严谨,避免NULL影响 COUNT(record_date) AS days_count FROM daily_rainfall -- 可选:过滤特定城市/时间范围 WHERE city = '北京' AND record_date BETWEEN '2023-01-01' AND '2023-12-31' GROUP BY rainfall_range -- 强制按区间顺序排序,避免字符串排序混乱(比如'10-20mm'不会跑到'0-10mm'前面) ORDER BY CASE rainfall_range WHEN '0-10mm' THEN 1 WHEN '10-20mm' THEN 2 WHEN '20-50mm' THEN 3 WHEN '50mm及以上' THEN 4 WHEN '异常值' THEN 5 WHEN '无记录' THEN 6 END;
关键说明:
CASE WHEN的区间条件必须和你的目标表完全匹配,尤其是边界值(比如10mm到底属于0-10还是10-20)COUNT(record_date)比COUNT(*)更严谨,因为如果某天没有记录,record_date可能为NULL,不会被统计进去- 加上
ORDER BY的CASE逻辑是为了保证结果的区间顺序和目标表一致,避免字符串排序的坑
方案二:动态区间(适合区间需要灵活调整的场景)
如果你的目标表本身就是一个区间配置表(比如有rainfall_ranges表,存了所有区间的上下限和名称),那用JOIN关联的方式更灵活,不用每次改SQL。
假设区间配置表结构:
表名rainfall_ranges:
range_id:区间ID(用来排序)range_name:区间名称(和目标表一致,比如'0-10mm')min_rainfall:区间最小值(比如0)max_rainfall:区间最大值(比如10,对于“50mm及以上”可以设为NULL)
完整SQL示例:
SELECT rr.range_name AS rainfall_range, COUNT(dr.record_date) AS days_count FROM rainfall_ranges rr -- 左连接源表,确保所有区间都能显示(哪怕没有对应天数) LEFT JOIN daily_rainfall dr ON dr.rainfall >= rr.min_rainfall -- 处理最大值为NULL的情况(比如“50mm及以上”) AND (dr.rainfall < rr.max_rainfall OR rr.max_rainfall IS NULL) -- 可选:过滤城市和时间 AND dr.city = '上海' AND dr.record_date BETWEEN '2023-01-01' AND '2023-12-31' GROUP BY rr.range_id, rr.range_name -- 按区间ID排序,保证顺序正确 ORDER BY rr.range_id;
关键说明:
- 用
LEFT JOIN可以确保即使某个区间没有对应天数,也会显示0,和目标表的结构更匹配 - 区间配置表修改后,SQL不用动,直接生效,适合需要经常调整区间的场景
- 注意处理
max_rainfall IS NULL的情况,对应“XX及以上”的区间
最后提醒
- 如果你的源表有多个城市,想要按城市+区间统计,只要在
GROUP BY里加上city字段就行 - 别忘了先检查源表的异常数据(比如NULL、负数),避免统计结果出错
内容的提问来源于stack exchange,提问作者Pedro Palermo
相关产品推荐
相关产品推荐

