选择一个既不是聚合函数也不是groupby子句中的列时没有得到错误



以下是leetcode的问题:

表:用户

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| name          | varchar |
+---------------+---------+

id是该表的主键。name是用户的名称。

表:Rides

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| user_id       | int     |
| distance      | int     |
+---------------+---------+

id是该表的主键。user_id是行进了距离"1"的用户的id;距离";。

编写一个SQL查询来报告每个用户所走的距离。

返回按travelled_tdistance降序排列的结果表,如果两个或多个用户行驶了相同的距离,则按他们的姓名升序排列。

查询结果格式如下例所示。

示例1:

输入:用户表:

+------+-----------+
| id   | name      |
+------+-----------+
| 1    | Alice     |
| 2    | Bob       |
| 3    | Alex      |
| 4    | Donald    |
| 7    | Lee       |
| 13   | Jonathan  |
| 19   | Elvis     |
+------+-----------+

Rides表:

+------+----------+----------+
| id   | user_id  | distance |
+------+----------+----------+
| 1    | 1        | 120      |
| 2    | 2        | 317      |
| 3    | 3        | 222      |
| 4    | 7        | 100      |
| 5    | 13       | 312      |
| 6    | 19       | 50       |
| 7    | 7        | 120      |
| 8    | 19       | 400      |
| 9    | 7        | 230      |
+------+----------+----------+

输出:

+----------+--------------------+
| name     | travelled_distance |
+----------+--------------------+
| Elvis    | 450                |
| Lee      | 450                |
| Bob      | 317                |
| Jonathan | 312                |
| Alex     | 222                |
| Alice    | 120                |
| Donald   | 0                  |
+----------+--------------------+

说明:埃尔维斯和李旅行了450英里,埃尔维斯是最热门的旅行者,因为他的名字按字母顺序比李小。Bob、Jonathan、Alex和Alice只有一次骑行,我们只按骑行的总距离排序。唐纳德没有乘坐任何交通工具,他行驶的距离是0。

以下是我的MySQL查询:

select
u.name,
coalesce(sum(r.distance), 0) as travelled_distance
from users u
left join rides r on u.id = r.user_id
group by u.id
order by travelled_distance desc, u.name asc; 

我已成功运行此查询。但我发现u.name列既不是聚合函数,也不是groupby子句中的列,这在使用groupby子句时是必需的。为什么这里没有错误?我在网上搜索了一下,发现MySQL的某些版本仍然可以运行这种场景而不会出错。有人能帮我澄清一下吗?(附言:使用groupbyu.id的原因是,在某些测试用例中,users表中可能存在重复的名称)。

您可以将u.nameMAX或添加到GROUP By

select
u.name,
coalesce(sum(r.distance), 0) as travelled_distance
from users u
left join rides r on u.id = r.user_id
group by u.id,u.name
order by travelled_distance desc, u.name asc; 
nametravelled_termance
Elvis450
Lee450
Bob317
Jonathan312
Alex222
Alice120
Donald0

选择u.name时可能没有看到错误的原因有两个,一个好,一个坏。

坏的原因可能是您没有启用ONLY_FULL_GROUP_BY sql_mode;这在默认情况下是启用的,但如果您升级了在配置文件中设置了sql_mode的旧服务器,或者选择设置sql_mode,则可能不会。您可以执行select @@SESSION.sql_mode以查看它是否在当前会话中启用。如果是这种情况,除非您有很多现有查询需要更新,否则您应该启用ONLY_FULL_GROUP _BY。然后,您将需要修改此查询(或者将u.name添加到按列表分组,如果u.id是主键,则这应该是无害的,或者选择ANY_VALUE(u.name)或MAX(u.name)等。

最好的理由是,如果您使用的是最新的mysql版本,并且u.id是唯一的或主键;然后,由于您是按u.id进行分组的,因此只能有一个u.name值,并且所选内容没有歧义。这被称为u.name;"功能相关";在u.id上,并且在当前的mysql版本中是允许的。(马里亚德布还不允许这样做,请参阅https://jira.mariadb.org/browse/MDEV-11588.)

相关内容

  • 没有找到相关文章

最新更新