PHP+MySQL后端项目:按学生时段查询request重复数据求助
解决按学生availability检索REQUEST时的数据重复问题
你的查询出现重复是因为一个学生对应多条availability记录,当用INNER JOIN关联request、student和availability时,每条request会和该学生的每一条符合条件的availability记录匹配,从而生成重复的request数据。以下是几种可行的解决方案:
方案1:使用DISTINCT去重
直接在SELECT后添加DISTINCT关键字,过滤掉重复的request记录:
SELECT DISTINCT DE.*, ET.picture AS picture_editor, CONCAT(ET.first_name, ' ', ET.name) AS name_editeur, DI.start, DI.end FROM request DE INNER JOIN student ET ON ET.id = DE.student_id INNER JOIN availability DI ON DI.student_id = DE.student_id WHERE DI.start < CAST('2022-12-31' AS DATETIME) AND DI.end > CAST('2022-09-11' AS DATETIME)
注:如果同一个request对应多个符合条件的availability,该方法会保留不同的availability时段组合,但request本身的核心字段不会重复。
方案2:使用EXISTS子查询(推荐)
若核心需求是找出所有属于“有符合指定时段availability的学生”的request,无需显示availability的具体时段,用EXISTS子查询可避免关联带来的重复,性能更优:
SELECT DE.*, ET.picture AS picture_editor, CONCAT(ET.first_name, ' ', ET.name) AS name_editeur FROM request DE INNER JOIN student ET ON ET.id = DE.student_id WHERE EXISTS ( SELECT 1 FROM availability DI WHERE DI.student_id = DE.student_id AND DI.start < CAST('2022-12-31' AS DATETIME) AND DI.end > CAST('2022-09-11' AS DATETIME) )
该方法仅检查学生是否存在符合条件的availability,不会因多条availability记录导致request重复。
方案3:使用GROUP BY分组聚合
若需要显示availability的信息,同时确保request不重复,可按request主键分组,用聚合函数处理availability字段(比如取最早的开始时间或最晚的结束时间):
SELECT DE.*, ET.picture AS picture_editor, CONCAT(ET.first_name, ' ', ET.name) AS name_editeur, MIN(DI.start) AS earliest_start, MAX(DI.end) AS latest_end FROM request DE INNER JOIN student ET ON ET.id = DE.student_id INNER JOIN availability DI ON DI.student_id = DE.student_id WHERE DI.start < CAST('2022-12-31' AS DATETIME) AND DI.end > CAST('2022-09-11' AS DATETIME) GROUP BY DE.id, ET.picture, ET.first_name, ET.name
注:MySQL 8.0+要求GROUP BY子句包含所有非聚合的SELECT字段,需按上述方式列出相关字段。
内容的提问来源于stack exchange,提问作者Josue Elonga
相关产品推荐
相关产品推荐

