MySQL没有正确排序结果

时间:2016-04-23 02:59:15

标签: mysql group-by sql-order-by

我有一个我正在开发和组织的应用程序的数据库。我有一个问题的问题,我无法弄清楚为什么。我将讨论相关的表格。第一个表包含有关该组织中各组的所有信息。第二个是组织成员。第三个包含成员可以属于的组。最后一个保存有关成员文件上载的信息。此查询的目的是返回按组月份和年份组织的成员上载的文件数。

这是查询

SELECT 
COUNT(archive.member_id) AS total,
EXTRACT(year FROM archive.submit_date) AS arc_year,
DATE_FORMAT(archive.submit_date, '%M') AS arc_month,
groups.weekday_id,
groups.group_name
FROM group_member_list
INNER JOIN groups ON group_member_list.group_id = groups.group_id
INNER JOIN archive ON group_member_list.member_id = archive.member_id
GROUP BY arc_year, arc_month, groups.group_name
ORDER BY archive.submit_date DESC ,groups.weekday_id ASC

这是我的测试数据的输出

total   arc_year   arc_month weekday_id   group_name
 3       2016       April      4          Wednesday group
 4       2016       April      7          Saturday group
 4       2016       April      1          Sunday group
 3       2016       March      1          Sunday group
 3       2016       March      4          Wednesday group
 4       2016       March      7          Saturday group
 3       2016       February   1          Sunday group
 3       2016       February   4          Wednesday group
 4       2016       February   7          Saturday group
 3       2016       January    1          Sunday group
 3       2016       January    4          Wednesday group
 4       2016       January    7          Saturday group
 3       2015       December   1          Sunday group
 3       2015       December   4          Wednesday group
 4       2015       December   7          Saturday group

一切正常,除了前三个结果没有订购其他一切。我无法弄清楚为什么。

3 个答案:

答案 0 :(得分:3)

MySQL 根据ORDER BY子句中的表达式正确排序结果。

这不是您期望的订单。您观察到按预期顺序排序的某些行的事实是巧合的。

问题在于ORDER BY子句中的表达式。要理解这种行为,要了解MySQL为何按行排序行,我们可以将ORDER BY子句中的列/表达式添加到查询的SELECT列表中。

SELECT ... 
     , archive.submit_date

 GROUP BY arc_year, arc_month, groups.group_name
 ORDER BY archive.submit_date DESC, groups.weekday_id ASC
          ^^^^^^^^^^^^^^^^^^^

当你查看返回的`submit_date`的值时,你会看到MySQL 遵守ORDER BY规范:

arc_year arc_month submit_date weekday_id group_name
-------- --------- ----------- ---------- --------------- 
2016     April     2016-04-06   4          Wednesday group
2016     April     2016-04-09   7          Saturday group
2016     April     2016-04-10   1          Sunday group 

您可能不期望的是submit_date的特定值。

`submit_date`返回的值是 indeterminate 。结果集中的`submit_date`列将从组中的行分配一个值。但它任何值。它不能保证是最低值,最后一个值,第一个值或最高值。

在 GROUP BY操作之后执行ORDER BY操作。为`submit_date`返回 indeterminate 值,然后使用为`submit_date`返回的值对行进行排序。

(注意:其他SQL数据库会在此查询中引发错误。该错误与在表达式不包含时在ORDER BY子句(或SELECT列表)中引用"非聚合表达式"有关。 #39; t 出现在GROUP BY子句中。默认安装的MySQL启用了一个特定于MySQL的GROUP BY扩展,允许执行此查询。我们可以让MySQL更紧密地遵守SQL标准(并为此查询返回错误),在会话的sql_mode中包含" ONLY_FULL_GROUP_BY"。

修复程序更改查询以更改ORDER BY以指定其他表达式。例如:

ORDER BY DATE_FORMAT(archive.submit_date,'%Y%m') DESC, groups.weekday_id ASC

wiil返回这样的内容:

arc_year arc_month yyyymm      weekday_id group_name
-------- --------- ----------- ---------- --------------- 
2016     April     201604      1          Sunday group 
2016     April     201604      4          Wednesday group
2016     April     201604      7          Saturday group

(没有必要在SELECT列表中的ORDER BY中包含表达式。我们这样做只是为了让我们能够"看到"发生了什么。)

答案 1 :(得分:1)

原因如下:
它在工作日正确排序 问题是,工作日可能由groups.group_name“分组”,只显示一个(第一个)工作日。

答案 2 :(得分:0)

您只按年份和月份进行分组,但首先按确切日期排序,然后按工作日排序。因此,如果有一个案例,其中较早的工作日直到该月的第二个(或更晚)周才有数据 - 例如4月3日星期日没有数据,但4月6日星期四确实 - 然后后者将首先出现。

建议:您是否关心按日期排序?如果没有(因为你还没有输出)为什么不删除它?如果由于某种原因是,可以按优先级排序。无论如何,在没有数据的情况下,我可以告诉他们。