首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >顺序是在区分之前还是之后适用?

顺序是在区分之前还是之后适用?
EN

Stack Overflow用户
提问于 2012-06-05 21:10:11
回答 3查看 3.6K关注 0票数 6

在MySQL查询中,当使用DISTINCT选项时,是否在删除重复项之后应用ORDER BY?如果没有,是否有办法使它这样做?我觉得我的代码出了点问题。

编辑

这里有一些更多的信息是什么导致了我的问题。我知道,乍一看,这个顺序并不重要,因为我处理的是重复的行。但是,情况并不完全如此,因为我使用INNER JOIN对行进行排序。

假设我有一个论坛线程表,其中包含以下数据:

代码语言:javascript
复制
+----+--------+-------------+
| id | userid |    title    |
+----+--------+-------------+
|  1 |      1 | Information |
|  2 |      1 | FAQ         |
|  3 |      2 | Support     |
+----+--------+-------------+

在另一张表格中,我也有一组类似这样的帖子:

代码语言:javascript
复制
+----+----------+--------+---------+
| 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查询来获取所有线程,然后根据最新的帖子对它们进行排序(假设ids较高的帖子是最近的:

代码语言:javascript
复制
SELECT t.*
FROM Threads t
INNER JOIN Posts p ON t.id = p.threadid
ORDER BY p.id DESC

这可以工作,并生成如下内容:

代码语言:javascript
复制
+----+--------+-------------+
| 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。然而,这产生了以下结果:

代码语言:javascript
复制
+----+--------+-------------+
| id | userid |    title    |
+----+--------+-------------+
|  3 |      2 | Support     |
|  2 |      1 | FAQ         |
|  1 |      1 | Information |
+----+--------+-------------+

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

是这样吗,还是我分析得不对?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-05 21:51:22

有两件事需要理解:

  1. 一般来说,除非指定了一个无序子句,否则结果集是ORDER BY;如果您指定了一个非严格命令 (即非唯一列上的ORDER BY ),则在结果集中显示相同顺序的记录的顺序是未定义的。 我怀疑您可能指定了这样一个非严格的顺序,这是问题的根源:通过在一组列上指定ORDER BY来确保您的排序是严格的,这些列足以唯一地标识您关心其在结果集中的最终位置的每条记录。
  2. GROUP BY,它将使结果按分组列排序;也就是说,SELECT DISTINCT a, b, c FROM t将生成一个结果集,该结果集看起来好像已经应用了ORDER BY a, b, c。同样,指定足够严格的命令以满足您的需要将覆盖此效果。

在您的更新之后,考虑到我上面的第2点,显然分组结果以实现DISTINCT的效果使得不可能通过非分组列p.id进行排序;相反,您希望:

代码语言:javascript
复制
SELECT   t.*
FROM     Threads t INNER JOIN Posts p ON t.id = p.threadid
GROUP BY t.id
ORDER BY MAX(p.id) DESC
票数 5
EN

Stack Overflow用户

发布于 2012-06-05 21:12:55

DISTINCT通知MySQL如何为您构建行集,ORDER BY给出了该行集应该如何表示的提示。所以答案是:DISTINCT优先,ORDER BY最后。

票数 1
EN

Stack Overflow用户

发布于 2012-06-05 21:28:52

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

但是,如果也使用GROUP BY,则此将影响最终输出。在本例中,ORDER BY是在GROUP BY之后执行的,这将返回意外的结果(假设您期望在分组之前执行排序)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10905026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档