不使用distinct如何保证SQL多表关联查询结果值对的唯一性
问题根因
重复值对产生的核心原因是同一城市存在多名学生选修同一门课程,每一条学生选课记录都会对应生成一行(address, type)结果,自然会出现重复条目。你反馈使用DISTINCT依旧无法去重,大概率是字段存在肉眼不可见的异常字符(比如地址末尾带空格、换行符),或是查询时误将其他字段加入了返回列表,理论上SELECT DISTINCT address, type是可以实现值对去重的。
不用DISTINCT的解决方案
方案1:GROUP BY分组(适用需额外统计的场景)
按返回的两个字段分组,相同值对会自动合并为一行,大数据量下性能优于DISTINCT,还可扩展其他分组统计逻辑:
SELECT S.address, C.type FROM Students S INNER JOIN TakingCourse TC ON S.id = TC.student_id INNER JOIN Courses C ON TC.course_id = C.id GROUP BY S.address, C.type
如果需要额外统计该城市选这门课的学生人数,只需在查询列加COUNT(DISTINCT S.id) as student_count即可。
方案2:EXISTS半连接(适用超大数据量场景)
不需要遍历所有选课记录,只要判断「某城市是否存在至少一名学生选了某门课」就停止匹配,性能最优:
SELECT S.address, C.type FROM (SELECT DISTINCT address, id FROM Students) S INNER JOIN (SELECT DISTINCT id, type FROM Courses) C WHERE EXISTS ( SELECT 1 FROM TakingCourse TC WHERE TC.student_id = S.id AND TC.course_id = C.id )
性能优化建议
因为你提到表数据量较大,可以添加以下索引大幅提升查询速度:
TakingCourse表加(student_id, course_id)联合索引Students表加(id, address)联合索引Courses表加(id, type)联合索引
内容的提问来源于stack exchange,提问作者vivalasana
相关产品推荐
相关产品推荐

