[英]A query works fine in MySQL and gives 'in select clause is neither an aggregate nor in the group by clause' error in snowflake
[英]Not getting an error when select a column that is not an aggregate function nor in the group by clause
這是來自 leetcode 的問題:
表:用戶
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
id 是該表的主鍵。 name 是用戶的名稱。
表:游樂設施
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| user_id | int |
| distance | int |
+---------------+---------+
id 是該表的主鍵。 user_id 是行進距離“distance”的用戶的 id。
編寫一個 SQL 查詢來報告每個用戶走過的距離。
返回按 travelled_distance 降序排列的結果表,如果兩個或兩個以上的用戶行駛距離相同,則按姓名升序排列。
查詢結果格式如下例。
示例 1:
輸入:用戶表:
+------+-----------+
| id | name |
+------+-----------+
| 1 | Alice |
| 2 | Bob |
| 3 | Alex |
| 4 | Donald |
| 7 | Lee |
| 13 | Jonathan |
| 19 | Elvis |
+------+-----------+
游樂設施表:
+------+----------+----------+
| 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 |
+------+----------+----------+
Output:
+----------+--------------------+
| 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這個列既不是聚合function也不在group by子句中,在使用group by子句的時候是需要的。 為什么這里沒有報錯? 上網查了下,MySQL的某些版本仍然可以運行這個場景不報錯。 有人可以為我澄清一下嗎? (PS 使用group by u.id 的原因是因為在某些測試用例中users 表中可以有重名)。
選擇 u.name 時可能沒有看到錯誤的原因有兩個,一個是好的,一個是壞的。
不好的原因是如果您沒有啟用 ONLY_FULL_GROUP_BY sql_mode; 這是默認打開的,但如果您升級了在配置文件中設置了 sql_mode 的舊服務器,或者選擇設置 sql_mode,則可能不會。 您可以執行select @@SESSION.sql_mode
以查看它是否在您當前的 session 中啟用。如果是這種情況,除非您有很多現有查詢需要更新,否則您應該啟用 ONLY_FULL_GROUP_BY。 然后您需要修改此查詢(將 u.name 添加到 group by 列表中,如果 u.id 是主鍵,這應該是無害的,或者選擇 ANY_VALUE(u.name) 或 MAX(u.name) 或喜歡。
很好的理由是,如果您使用的是最新的 mysql 版本並且 u.id 是唯一鍵或主鍵; 那么,由於您是按 u.id 分組的,因此只能有一個 u.name 值,並且所選擇的內容沒有歧義。 這被稱為 u.name “功能上依賴於”u.id,並且在當前的 mysql 版本中是允許的。 (在mariadb還不允許,見https://jira.mariadb.org/browse/MDEV-11588。 )
您可以MAX
u.name 或將其添加到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;
名稱 | 旅行距離 |
---|---|
貓王 | 450 |
李 | 450 |
鮑勃 | 317 |
喬納森 | 312 |
亞歷克斯 | 222 |
愛麗絲 | 120 |
唐納德 | 0 |
select
MAX(u.name) 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, name asc;
名稱 | 旅行距離 |
---|---|
貓王 | 450 |
李 | 450 |
鮑勃 | 317 |
喬納森 | 312 |
亞歷克斯 | 222 |
愛麗絲 | 120 |
唐納德 | 0 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.