我有一个我正在开发和组织的应用程序的数据库。我有一个问题的问题,我无法弄清楚为什么。我将讨论相关的表格。第一个表包含有关该组织中各组的所有信息。第二个是组织成员。第三个包含成员可以属于的组。最后一个保存有关成员文件上载的信息。此查询的目的是返回按组月份和年份组织的成员上载的文件数。
这是查询
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
一切正常,除了前三个结果没有订购其他一切。我无法弄清楚为什么。
答案 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日星期四确实 - 然后后者将首先出现。
建议:您是否关心按日期排序?如果没有(因为你还没有输出)为什么不删除它?如果由于某种原因是,可以按优先级排序。无论如何,在没有数据的情况下,我可以告诉他们。