如何在MySQL中通过多左连接与排名查询去重的task_id
优化MySQL多左连接+RANK()实现去重task_id查询
原查询的核心问题是:通过LEFT JOIN关联任务标签表与标签表后,单个任务若对应多个标签会返回重复的task_id,导致结果冗余,且RANK()会基于所有重复行计算排名,不符合去重需求。
优化思路
- 先对每个任务聚合出最高优先级(若一个任务关联多个标签,取优先级最高的用于排名);
- 基于聚合后的唯一任务数据应用RANK()函数,确保每个task_id仅出现一次。
优化后SQL
SELECT task_id, max_priority, RANK() OVER (ORDER BY max_priority DESC) AS `rank` FROM ( SELECT t.id AS task_id, MAX(tg.priority) AS max_priority FROM `dbbace69-6968-4b4d-9ac4-bcd8394beeab_tasks` t LEFT JOIN `dbbace69-6968-4b4d-9ac4-bcd8394beeab_task_tag` tt ON tt.task_id = t.id LEFT JOIN `tags` tg ON tt.tag_id = tg.id WHERE t.project_stage_id = 'b30896ef-5737-4eeb-a988-346103ec2e80' AND t.deleted_at IS NULL GROUP BY t.id -- 按任务ID聚合,保证每个task_id唯一 ) AS task_priority ORDER BY `rank`;
关键优化点
- GROUP BY聚合:通过
GROUP BY t.id确保子查询中每个task_id仅返回一行,避免重复数据; - MAX(priority):取单个任务关联标签中的最高优先级,确保排名逻辑符合业务预期;
- 别名简化:用
t、tt、tg替代冗长的表名,提升SQL可读性; - RANK()外层计算:在聚合后的唯一数据集上计算排名,保证排名结果准确。
可选调整
如果需要将无标签任务的优先级设为默认值(避免NULL排在末尾),可以用COALESCE函数替换MAX(tg.priority):
COALESCE(MAX(tg.priority), 0) AS max_priority
内容的提问来源于stack exchange,提问作者Dương Hoàng Văn
相关产品推荐
相关产品推荐

