簡體   English   中英

選定的項目不必出現在 GROUP BY 子句中或用於聚合 function

[英]selected items don't have to appear in the GROUP BY clause or be used in an aggregate function

我被教導並聽說在 sql/mysql 中, select子句中的項目必須出現在 GROUP BY 子句中或在聚合 function 中使用,這里

但是,下面的示例可能改變了我的想法。

兩張表:學生(sid是關鍵)

sid  | name | email
========================
99901| mike | mike@a.edu
99902| jane | jane@b.edu
99903| peter| pete@b.edu

Take(sid+oid一起是key,oid代表offering id)

sid  | oid| grade
==================
99901| 1  | 100
99901| 2  | 30
99901| 3  | 40
99902| 4  | 100
99902| 5  | 100
99902| 6  | 40
99903| 6  | 95

問題:我想找到每個上過至少 2 門課程的學生的 sid、姓名和平均成績。

答案

select s.sid, name, avg(grade) as average
from Student as s, Took as t
where s.sid = t.sid
group by s.sid
having count(*) >= 2;

結果:

sid  | name | avgerage
=======================
99901| mike | 56.6667
99902| jane | 80.0000

基於必須出現在 GROUP BY 子句中或在聚合 function 中使用,查詢應該是不正確的,因為name既不在組子句中,也不在聚合 function 中。

我看了一些帖子, 的理解是,雖然name既不在組子句中,也不是聚合 function,我們按sid分組,這是鍵,每個sid只對應一個name ,所以它不會返回多個選項sql 不知道返回哪一個。 為了確認我的理解,如果我 select 多一列email ,它仍然可以; 但是如果我 select oid ,它會給出錯誤,因為每個sid對應多個oid

有人可以糾正我的理解,如果它是錯誤的,或者更詳細地說明這個陳述: must appear in the GROUP BY clause or be used in an aggregate function

謝謝。

第一次編輯

順便說一句,我在 MySQL 8.0.17 中進行了測試

第二次編輯

當您閱讀下面的答案/評論時,只是有用鏈接的摘要。

功能依賴

SQL 標准變更

首先,您應該使用正確的、顯式的JOIN語法:

select s.sid, s.name, avg(grade) as average
from Student s join
     Took t
     on s.sid = t.sid
group by s.sid
having count(*) >= 2;

這將起作用,因為稱為功能依賴項。 基本上,這是標准的一部分:如果您group by ,那么您可以包含該表中的任何列。

是有關該主題的文檔。

也就是說,因為數據庫知道s.sid是唯一的,所以使用其他列是安全的。 這是標准的一部分。 我知道的唯一支持這一點的其他通用數據庫是 Postgres。

你被教對了。

根據 SQL 標准,當您使用GROUP BY時, SELECT子句中可能出現的列分為三類:

  1. GROUP BY子句中包含的列。 在這種情況下,您有s.sid
  2. 聚合列。 在這種情況下,您有avg(grade)
  3. 案例 #1 的功能相關列。 由於s.sid是表的 PK,因此您可以包含s.name而不聚合它。

所以一切都很好。

但是,您應該知道 MySQL 5.7.4 及更早版本確實允許您以非聚合形式包含其他列。 這是我個人認為容易出錯的 MySQL 的錯誤/功能。 如果你這樣做,MySQL 將默默地隨機選擇一個值,而不聚合它,也不會告訴你。

可以通過在 MySQL 的較新版本中使用ONLY_FULL_GROUP_BY配置參數(正如@Shawn 在評論中指出的那樣)打開此功能,以允許運行舊/壞查詢。 不過,我會盡量避免使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM