gpt4 book ai didi

mysql - 所选项目不必出现在 GROUP BY 子句中或用于聚合函数

转载 作者:行者123 更新时间:2023-11-29 05:01:28 25 4
gpt4 key购买 nike

我被教导和听说在 sql/mysql 中,select 子句中的项目必须出现在 GROUP BY 子句中或用于聚合函数,如 here

但是,下面的例子可能改变了我的想法。

两个表:学生(sid是关键)

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

取了(sid+oid一起是关键,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门类(class)的每个学生的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子句中或在聚合函数中使用,查询应该是不正确的,因为name既不在group子句中也不在聚合中功能。

我看了一些帖子和 this ,我的理解是虽然 name 既不是在 group 子句中也不是聚合函数,我们按 sid 分组,这是关键和每个sid只对应一个name,所以不会返回多个sql不知道返回哪个的选项。为了确认我的理解,如果我再选择一列email,它仍然可以;但是如果我选择 oid,它会出错,因为每个 sid 对应于多个 oid

有人可以纠正我的理解,如果它是错误的或详细说明这个声明:必须出现在 GROUP BY 子句中或用于聚合函数

谢谢。

第一次编辑:

顺便说一句,我在 MySQL 8.0.17 中测试过

第二次编辑:

当您阅读下面的答案/评论时,只是有用链接的摘要。

Functional depedency

SQL standard change

最佳答案

首先,您应该使用正确、明确的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 一个主键或唯一键,那么您可以包括该表中的任何列。

Here是关于这个主题的文档。

也就是说,因为数据库知道 s.sid 是唯一的,所以使用其他列是安全的。这是标准的一部分。据我所知,唯一支持此功能的其他通用数据库是 Postgres。

关于mysql - 所选项目不必出现在 GROUP BY 子句中或用于聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58222751/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com