6

在 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 |
+----+--------+-------------+

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

是这种情况,还是我分析错误?

4

3 回答 3

5

有两点要理解:

  1. 一般来说,除非您指定子句,否则结果集是无序的;ORDER BY在您指定非严格顺序的范围内(即ORDER BY在非唯一列上),在该顺序下相等的记录出现在结果集中的顺序是未定义的。

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

  2. DISTINCT可以使用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
于 2012-06-05T21:51:22.467 回答
1

DISTINCT告知 MySQL 如何为您构建行集,ORDER BY并提示该行集应该如何呈现。所以答案是:DISTINCT第一,ORDER BY最后。

于 2012-06-05T21:12:55.113 回答
1

DISTINCT在大多数情况下,应用和的顺序ORDER BY不会影响最终输出。

但是,如果您还使用GROUP BY,这影响最终输出。在这种情况下,在ORDER BY之后执行GROUP BY这将返回意外结果(假设您希望在分组之前执行排序)。

于 2012-06-05T21:28:52.207 回答