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

如何按CITY和PROD分组查询并保留P1、P2列及最小P3值

解决分组取最小P3并保留对应P1、P2的问题

这个场景太常见了!GROUP BY确实只能返回你指定的分组字段和聚合计算结果,没法直接把P1、P2这类非分组列带回来。我给你几个实用的解决方案,你可以根据自己用的数据库版本和具体需求来选:

1. 窗口函数法(推荐,适配现代数据库)

如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),这是最简洁易维护的方法。我们可以用ROW_NUMBER()或者RANK()函数,按CITY和PROD分区,再按P3升序排序,最后筛选出每组的第一条记录:

WITH ranked_data AS (
    SELECT 
        CITY, PROD, P1, P2, P3,
        -- 按CITY+PROD分组,P3最小的行排第1
        ROW_NUMBER() OVER (PARTITION BY CITY, PROD ORDER BY P3 ASC) AS row_num
    FROM MYTABLE
)
SELECT CITY, PROD, P1, P2, P3
FROM ranked_data
WHERE row_num = 1;

注意:如果同一组内有多行的P3都是最小值,ROW_NUMBER()会随机选其中一行返回。要是想保留所有P3为组内最小值的行,把ROW_NUMBER()换成RANK()即可。

2. 子查询关联法(兼容旧版本数据库)

如果你的数据库版本较低(比如MySQL 5.x)不支持窗口函数,可以先通过子查询找出每组的最小P3,再和原表关联匹配,从而拿到对应的P1、P2:

SELECT t.CITY, t.PROD, t.P1, t.P2, t.P3
FROM MYTABLE t
INNER JOIN (
    -- 先分组获取每组的最小P3
    SELECT CITY, PROD, MIN(P3) AS min_p3
    FROM MYTABLE
    GROUP BY CITY, PROD
) g 
ON t.CITY = g.CITY 
AND t.PROD = g.PROD 
AND t.P3 = g.min_p3;

这种方法会返回所有P3等于组内最小值的行,和RANK()的效果一致。

3. IN子句法(写法更简洁)

逻辑和关联法类似,用多列IN子句来匹配分组和最小P3的组合:

SELECT CITY, PROD, P1, P2, P3
FROM MYTABLE
WHERE (CITY, PROD, P3) IN (
    SELECT CITY, PROD, MIN(P3)
    FROM MYTABLE
    GROUP BY CITY, PROD
);

不过要注意,部分旧数据库可能不支持多列IN的语法,使用前可以先测试一下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:51:24