MySQL 没有正确排序结果

MySQL not properly ordering results

我有一个数据库,用于我正在为组织开发的应用程序。我的其中一个查询有问题,我不知道为什么。我将讨论相关的tables。首先 table 包含有关该组织中各个组的所有信息。二是举办会员组织。第三个持有成员可以属于的组。最后一个保存有关成员文件上传的信息。此查询的目的是 return 按组月和年组织的成员上传了多少文件。

这是查询

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 个结果未排序外,其他一切正常。我不知道为什么。

原因如下:
它按工作日正确排序。
问题是,工作日可能 "grouped" 到 groups.group_name,并且只显示一个(第一个)工作日。

您仅按年和月分组,但首先按确切日期排序,然后按工作日排序。因此,如果存在这样一种情况,即较早的工作日直到该月的第二周(或更晚的一周)才具有数据 - 例如4 月 3 日星期日没有数据,但 4 月 6 日星期三有数据 - 那么后者将首先出现。

建议:你关心按日期排序吗?如果不是(因为你无论如何都不输出它)为什么不删除它?如果是,出于某种原因,可能会将其降低排序优先级。无论如何,这就是我在没有数据的情况下所能知道的。

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

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

问题出在 ORDER BY 子句中的表达式中。要了解此行为,了解为什么 MySQL 以这种方式对行进行排序,我们可以将 ORDER BY 子句中的 columns/expressions 添加到查询的 SELECT 列表中。

SELECT ... 
     , archive.submit_date

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

当您查看 returned 的 `submit_date` 的值时,您会发现 MySQL 按规格订购:

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”return编辑的值是不确定。结果集中的“submit_date”列将从组中的一行中分配一个值。但它是 any 值。不保证是最低值、最后值、第一个值或最高值。

ORDER BY 操作在GROUP BY 操作之后 执行。 不确定 值被 returned 用于 `submit_date`,然后使用值 returned 用于 `submit_date 对行进行排序]`.

(注意:其他 SQL 数据库会对此查询抛出错误。该错误与在 ORDER BY 子句(或 SELECT 列表)中引用 "non-aggregate expression" 有关当表达式 also 不出现在 GROUP BY 子句中时。默认安装 MySQL 启用 GROUP BY 的 MySQL-specific 扩展,允许执行此查询. 我们可以通过在 sql_mode 中包含 "ONLY_FULL_GROUP_BY" 来让 MySQL 更严格地遵守 SQL 标准(并且 return 此查询的错误) session.)

解决方法是更改​​查询以更改 ORDER BY 以指定不同的表达式。例如:

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

将 return 像这样:

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 中包含表达式。我们在这里这样做只是为了让我们可以 "see" 发生了什么。)