php - ORDER BY 应用在 DISTINCT 之前还是之后?

标签 php mysql sql-order-by

在 MySQL 查询中,当使用 DISTINCT 选项时,是否在删除重复项后应用 ORDER BY?如果没有,有什么办法让它这样做吗?我认为这会导致我的代码出现一些问题。

编辑:
以下是有关导致我的问题的原因的更多信息。我知道,乍一看,这个顺序并不重要,因为我正在处理重复的行。然而,情况并非完全如此,因为我正在使用 INNER JOIN 对行进行排序。

假设我有一张论坛主题表,其中包含以下数据:

+----+--------+-------------+
| id | userid |    title    |
+----+--------+-------------+
|  1 |      1 | Information |
|  2 |      1 | FAQ         |
|  3 |      2 | Support     |
+----+--------+-------------+

我在另一个表中也有一组这样的帖子:

+----+----------+--------+---------+
| id | threadid | userid | content |
+----+----------+--------+---------+
|  1 |        1 |      1 | Lorem   |
|  2 |        1 |      2 | Ipsum   |
|  3 |        2 |      2 | Test    |
|  4 |        3 |      1 | Foo     |
|  5 |        2 |      3 | Bar     |
|  6 |        3 |      5 | Bob     |
|  7 |        1 |      2 | Joe     |
+----+----------+--------+---------+

我正在使用以下 MySQL 查询来获取所有线程,然后根据最新帖子对它们进行排序(假设具有更高 ID 的帖子是最近的:

SELECT t.*
FROM Threads t
INNER JOIN Posts p ON t.id = p.threadid
ORDER BY p.id DESC

这行得通,并生成如下内容:

+----+--------+-------------+
| id | userid |    title    |
+----+--------+-------------+
|  1 |      1 | Information |
|  3 |      2 | Support     |
|  2 |      1 | FAQ         |
|  3 |      2 | Support     |
|  2 |      1 | FAQ         |
|  1 |      1 | Information |
|  1 |      1 | Information |
+----+--------+-------------+

但是,正如你所看到的,信息是正确的,但是有重复的行。我想删除此类重复项,所以我改用了 SELECT DISTINCT。但是,这产生了以下结果:

+----+--------+-------------+
| id | userid |    title    |
+----+--------+-------------+
|  3 |      2 | Support     |
|  2 |      1 | FAQ         |
|  1 |      1 | Information |
+----+--------+-------------+

这显然是错误的,因为“信息”线程应该在最上面。似乎使用 DISTINCT 会导致从上到下删除重复项,因此只剩下最后几行。这会导致排序出现一些问题。

是这样吗,还是我分析不正确?

最佳答案

需要理解的两件事:

  1. 一般来说,结果集是 unordered除非您指定一个 ORDER BY 子句;在您指定 non-strict order 的范围内(即 ORDER BY 在非唯一列上),在该排序下相等的记录出现在结果集中的顺序是未定义的。

    我怀疑您可能指定了这样一个非严格的顺序,这是您问题的根源:通过在一组足以唯一标识您关心的每条记录在结果集中的最终位置。

  2. DISTINCT may use GROUP BY ,这会导致结果按分组列排序;也就是说,SELECT DISTINCT a, b, c FROM t 将生成一个结果集,看起来好像已应用了 ORDER BY a, b, c。同样,指定足够严格的顺序以满足您的需求将覆盖此效果。


根据您的更新,请记住我上面的第 2 点,很明显,对结果进行分组以实现 DISTINCT 的效果使得无法按未分组的列 进行排序>p.id;相反,你想要:

SELECT   t.*
FROM     Threads t INNER JOIN Posts p ON t.id = p.threadid
GROUP BY t.id
ORDER BY MAX(p.id) DESC

关于php - ORDER BY 应用在 DISTINCT 之前还是之后?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10905026/

相关文章:

php - Laravel 定义复​​杂关系

mysql - 使用 Limit 从 a 到 z 排序

python - 使用 SQLite 进行复杂的 SQL 查询

php - 何时在 PHP 中将数据库结果作为对象和数组获取?为什么?

php - 使用 SQL 将新用户和用户元添加到数据库中

mysql - 如何用左连接替换 group by?

sql - 为什么 SQL 对子句顺序严格?

php - 如何找到大文件的crc32?

PHP类问题

mysql - 使用 mysql JOIN 后保存表