如何使用SQL函数查询各城市最大降雨天数(含并列值)
查询各城市最大降雨天数(含并列记录)的SQL实现
嘿,我来帮你搞定这个查询需求!首先咱们先明确下假设的表结构(毕竟你没给出具体表名和字段,我先按常见的情况来设定,你可以根据实际情况调整):假设我们有一张名为rain_data的表,包含以下字段:
city:城市名称(字符串类型)start_date:降雨开始日期(日期类型)end_date:降雨结束日期(日期类型)rain_days:降雨持续天数(整数类型,如果这个字段不是直接存储的,后面会讲怎么计算)
接下来我给你两种符合你要求的实现方式,都用到了SELECT、MAX,第二种还用到了CASE,完全满足你的需求:
方法一:子查询关联法(最通用)
这种方法适用于所有主流SQL方言(MySQL、PostgreSQL、SQL Server等),思路是先算出每个城市的最大降雨天数,再关联原表找出所有匹配的记录:
SELECT r.city, r.start_date, r.end_date, r.rain_days FROM rain_data r JOIN ( -- 先按城市分组,算出每个城市的最大降雨天数 SELECT city, MAX(rain_days) AS max_rain_days FROM rain_data GROUP BY city ) max_days ON r.city = max_days.city AND r.rain_days = max_days.max_rain_days ORDER BY r.city;
解释:
- 内层子查询
max_days会生成一个临时表,包含每个城市和它对应的最大降雨天数; - 把原表
rain_data和这个临时表关联,筛选出城市相同且降雨天数等于该城市最大值的所有记录,这样并列的最大值记录就都会被输出。
方法二:窗口函数+CASE标记法
如果你想用CASE函数来实现,那可以结合窗口函数MAX() OVER()来标记每条记录是否是该城市的最大值,再筛选出标记为最大值的行:
SELECT city, start_date, end_date, rain_days FROM ( SELECT city, start_date, end_date, rain_days, -- 用窗口函数算出当前城市的最大降雨天数 MAX(rain_days) OVER(PARTITION BY city) AS city_max_days, -- 用CASE标记当前记录是否是最大值 CASE WHEN rain_days = MAX(rain_days) OVER(PARTITION BY city) THEN 1 ELSE 0 END AS is_max FROM rain_data ) sub_query -- 只保留标记为最大值的记录 WHERE is_max = 1 ORDER BY city;
解释:
- 内层子查询里,
MAX(rain_days) OVER(PARTITION BY city)会给每条记录附上所属城市的最大降雨天数; CASE语句会判断当前记录的降雨天数是否等于该城市的最大值,是就标记为1,否则为0;- 外层查询只筛选出标记为1的记录,就能得到所有并列最大值的行。
特殊情况:如果降雨天数需要计算(而非直接存储)
如果你的表中没有rain_days字段,需要通过start_date和end_date计算(比如包含首尾两天的话,用DATEDIFF(end_date, start_date) + 1),那只需要把上面的rain_days替换成计算式即可,举个例子:
SELECT r.city, r.start_date, r.end_date, DATEDIFF(r.end_date, r.start_date) + 1 AS rain_days FROM rain_data r JOIN ( SELECT city, MAX(DATEDIFF(end_date, start_date) + 1) AS max_rain_days FROM rain_data GROUP BY city ) max_days ON r.city = max_days.city AND DATEDIFF(r.end_date, r.start_date) + 1 = max_days.max_rain_days ORDER BY r.city;
示例效果
假设你的表中有这些数据:
| city | start_date | end_date | rain_days |
|---|---|---|---|
| Auckland | 2013-11-30 | 2013-11-30 | 5 |
| Christchurch | 2013-11-10 | 2013-11-13 | 4 |
| Christchurch | 2013-11-20 | 2013-11-23 | 4 |
| Wellington | 2013-11-05 | 2013-11-07 | 3 |
执行查询后会得到:
Auckland 2013-11-30 2013-11-30 5 Christchurch 2013-11-10 2013-11-13 4 Christchurch 2013-11-20 2013-11-23 4 Wellington 2013-11-05 2013-11-07 3
完全符合你要的“并列最大值全部输出”的要求~
内容的提问来源于stack exchange,提问作者Jassica
相关产品推荐
相关产品推荐

