如何在SQL查询中移除ClassID列重复值且不删除源数据
解决方案
核心思路
通过分组排序逻辑实现需求:对相同ClassId的行设置优先级,5年级行优先级最高,最终每个ClassId仅保留优先级最高的1行,整个操作仅修改查询结果,不会改动源表数据。
实现方式1:窗口函数法(兼容MySQL 8.0+、PostgreSQL、SQL Server等主流新版本数据库)
这是最简洁通用的实现方案:
WITH ranked_class AS ( SELECT schoolno, schoolyear, schoolgrade, classname, classId, -- 按ClassId分组,组内5年级行排第一位 ROW_NUMBER() OVER ( PARTITION BY classId ORDER BY CASE WHEN schoolgrade = '5' THEN 1 ELSE 2 END ASC ) AS row_num FROM classgroup cg ) -- 仅保留每个ClassId排序第一的行 SELECT schoolno, schoolyear, schoolgrade, classname, classId FROM ranked_class WHERE row_num = 1;
注意:如果schoolgrade字段是数值类型,把条件里的'5'改为5即可。如果同一个ClassId下存在多条5年级行,可以在ORDER BY后追加额外排序规则,比如加schoolyear DESC取最新学年的行,避免出现意外重复。
实现方式2:关联匹配法(兼容MySQL 5.x等不支持窗口函数的旧版本数据库)
SELECT cg.schoolno, cg.schoolyear, cg.schoolgrade, cg.classname, cg.classId FROM classgroup cg LEFT JOIN classgroup cg2 ON cg.classId = cg2.classId AND cg.schoolgrade != '5' AND cg2.schoolgrade = '5' -- 过滤掉存在对应5年级行的非5年级行 WHERE cg2.classId IS NULL;
补充说明
如果你的需求中,要求ClassId没有对应5年级行时直接剔除该ClassId的所有行,可以在上述查询的过滤条件中追加AND schoolgrade = '5'即可。
内容的提问来源于stack exchange,提问作者Tito
相关产品推荐
相关产品推荐

