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" 发生了什么。)
我有一个数据库,用于我正在为组织开发的应用程序。我的其中一个查询有问题,我不知道为什么。我将讨论相关的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" 发生了什么。)