为啥使用 order by 添加时 distinct(column) 会返回重复项?

Posted

技术标签:

【中文标题】为啥使用 order by 添加时 distinct(column) 会返回重复项?【英文标题】:Why does distinct(column) return a duplicate when added with order by?为什么使用 order by 添加时 distinct(column) 会返回重复项? 【发布时间】:2021-07-31 01:53:03 【问题描述】:

SQL:

select distinct
    h.teacher_id,
    h.last_updated_at,
    c.name
from sometable h 
   inner join class c on h.teacher_id=c.id
   where last_updated_at is not null
   order by last_updated_at desc limit 5;

我收到重复的 teacher_id 作为回应。我哪里错了?我想返回上次更新的教师姓名和 ID。

【问题讨论】:

您误解了distinct 的作用。它适用于整行。 【参考方案1】:

SELECT DISTINCT * FROM ... 返回唯一的。同一位老师可以多次出现,而其他栏则不同。

如果您希望行在选定列上是唯一的,请使用DISTINCT ON。喜欢:

SELECT DISTINCT ON (teacher_id)
       h.teacher_id,
     , h.last_updated_at
     , c.name
FROM   ...
ORDER  BY teacher_id, last_updated_at DESC
LIMIT  5;

详细解释:

Select first row in each GROUP BY group?

如果您想要不同的ORDER BY,请参阅:

PostgreSQL DISTINCT ON with different ORDER BY

【讨论】:

是的,我也这样做了。如果teacher_id 不只是id,它是一个唯一的字符串id。因此,当我添加teacher_id 时,整个事情都会发生变化。 @BharatBittu:链接的答案解释了DISTINCT ON 的每一个细节。【参考方案2】:

您可能会看到有问题的teacher_id 有多个与之关联的类。如果您需要每位教师和他们领导的所有班级的一份记录,您可以使用STRING_AGG(c.name) 之类的东西(取决于您的 PostgreSQL 版本)。或者,您可以使用COUNT(c.name) 返回他们领导的班级数量。

在这两种情况下,您都需要GROUP BY 教师的 ID 和上次更新。

【讨论】:

以上是关于为啥使用 order by 添加时 distinct(column) 会返回重复项?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ORDER BY 子句中的绑定参数不对结果进行排序?

为啥 Sqlite 不使用这个 ORDER BY 的索引?

防止实体框架在使用 Include 时添加 ORDER BY

为啥 ORDER BY 不对这个查询进行排序?

为啥 MySQL 查询在使用 LIMIT 和 Order BY 时会变慢?

如果 ASC 和 DESC 混合使用,为啥 MySQL 不能为 ORDER BY 使用索引?