从 LEFT JOIN 查询中删除重复项

Posted

技术标签:

【中文标题】从 LEFT JOIN 查询中删除重复项【英文标题】:Remove duplicates from LEFT JOIN query 【发布时间】:2013-10-24 14:16:48 【问题描述】:

我正在使用以下 JOIN 语句:

SELECT * 
FROM students2014 
JOIN notes2014 ON (students2014.Student = notes2014.NoteStudent) 
WHERE students2014.Consultant='$Consultant' 
ORDER BY students2014.LastName

检索学生列表 (students2014) 和存储在 (notes2014) 中的每个学生的相应笔记。

每个学生在 notes2014 表中都有多个笔记,每个笔记都有一个与每个学生的唯一 ID 对应的 ID。上面的语句返回了一个学生列表,但复制了每个有多个笔记的学生。我只想显示每个学生的最新笔记(由最高的笔记 ID 确定)。

这可能吗?

【问题讨论】:

Returning only latest result from LEFT JOIN的可能重复 您好。请不要再问你的问题 - 它会浪费精力,可以在其他地方更有效地使用。 【参考方案1】:

您需要根据您从选择中获得的 MAX noteId 再次加入。

应该这样做(未经测试;下次我建议您粘贴指向http://sqlfiddle.com/ 的链接以及您的表结构和一些示例数据。

SELECT * 
FROM students s
LEFT JOIN (
    SELECT MAX(NoteId) max_id, NoteStudent
    FROM notes  
    GROUP BY NoteStudent
) aux ON aux.NoteStudent = s.Student
LEFT JOIN notes n2 ON aux.max_id = n2.NoteId

如果我可以这么说,表被称为students2014 的事实是一个很大的代码气味。使用学生表和年份字段会更好,原因有很多(只是几个:您不需要每年更改数据库结构,跨年份查询要容易得多,等等) .也许你“继承”了这一点,但我想我会提到它。

【讨论】:

【参考方案2】:

按 studentId 分组查询并选择 noteId 的 MAX

试试:

SELECT 
students2014.Student,
IFNULL(MAX(NoteId),0)
FROM students2014 
LEFT JOIN notes2014 ON (students2014.Student = notes2014.NoteStudent) 
WHERE students2014.Consultant='$Consultant'
GROUP BY students2014.Student 
    ORDER BY students2014.LastName

【讨论】:

我认为我们越来越近了,但是这不包括列表中没有任何笔记的任何学生。我也需要显示那些目前没有任何相应注释的。 左外连接而不是仅仅连接 我想我很快就谈过了。这确实消除了重复,并显示了所有学生(即使是那些没有笔记的学生)唯一的问题是它显示的是输入的第一个笔记,而不是数字 ID 最高的笔记。你知道为什么会这样吗? 看来 MAX(NoteID) 实际上根本没有执行任何功能。我可以删除它并使用 LEFT OUTER JOIN 仍然返回相同的结果... GROUP BY 正在删除您的重复项。 MAX 功能仅向您显示可用的最高 NoteID。问题是notes表连接是基于studentID的。

以上是关于从 LEFT JOIN 查询中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章

从 LEFT OUTER JOIN 中删除重复项

如何在从多个表中获取多行的同时删除 sql JOIN 中的重复项

删除左表上的重复项,同时在右表SELECT JOIN上保留重复项

如何修改此工作 SQL SELECT/JOIN 查询以删除重复项?

从 SQL Join 中删除重复项

从 SQLite 中的 SQL 查询结果中删除重复项