繁体   English   中英

SQL中GROUP BY的基本用法

[英]Basic usage of GROUP BY in SQL

我正在努力了解此查询中对GROUP BY的使用,并正在寻求澄清:

Flights(flno: integer, from: string, to: string, distance: integer, departs: time, arrives: time, price: real)
Aircraft(aid: integer, aname: string, cruisingrange: integer)
Certified(eid: integer, aid: integer)
Employees(eid: integer, ename: string, salary: integer)

问题是:对于巡航距离超过1000英里的所有飞机,请找到飞机的名称以及获得该飞机认证的所有飞行员的平均工资。

SELECT Temp.name, Temp.AvgSalary
FROM ( SELECT A.aid, A.aname AS name,
              AVG (E.salary) AS AvgSalary
       FROM Aircraft A, Certified C, Employees E
       WHERE A.aid = C.aid AND
             C.eid = E.eid AND A.cruisingrange > 1000
       GROUP BY A.aid, A.aname ) AS Temp

为什么在这里需要GROUP BY 以下查询不会返回飞机和相应的薪水,还是会返回并非特定于每架飞机的所有员工的平均薪水?

       SELECT A.aname, AVG(E.salary)
       FROM Aircraft A, Certified C, Employees E
       WHERE A.aid = C.aid AND
             C.eid = E.eid AND A.cruisingrange > 1000

使用GROUP BY是否会更改表格的格式,以便使用GROUP BY A.aid将指定我们仅对飞机表格进行分组,而使已认证和雇员表格保持不变?

要求GROUP BY正确执行聚合(在这种情况下,取平均值)。

如果您不进行任何分组,MySQL将在整个表上进行此聚合。 换句话说,如果您使用的是上一个查询,它将返回巡航范围超过1000的所有飞机的平均薪水,而不会区分哪个飞机。 尝试一下,您将看到此行为。

但是,如果您使用GROUP BY子句在这里,你会看到平均架飞机具有航程超过1000,这是你想要的。 没有它,您将获取所有飞机的平均值。

在一些样本数据上尝试这些查询,行为上的差异将变得更加明显。


编辑

关于您的最后几句话:是的,我们对认证表或员工表不做任何事情。 退一步,问题针对每架飞机 很多时候,如果给出问题说明,说明您需要为哪一组项目提供结果,那么将其作为分组依据子句是一个很好的开始。

用SQL编写AVG(...)时,这是一种本能,请使用GROUP BY指定要定义平均值组的条件。 尽管有GROUP BY子句,它只会将所有E.salary分组并取平均值。

每当您选择聚合函数(如AVG,SUM,MAX,MIN等)以及其他列时,都必须按非聚合函数或常量的所有列进行分组。 我能想到的唯一例外是使用窗口函数时(MySQL中不可用)。

在此示例中,我不清楚为什么未从Temp选择a.aid 如果有两架名称相同但编号不同的飞机,您会看到类似...的结果

aname   avg
------  -------
747     100,000
747     110,000
DC10     90,000

...这两个记录是针对同名不同飞机的(747)

到这里的小组说,要平均每架飞机的薪水,从而为您提供每架飞机的平均薪水...因为其中仅包括您要查找的平均飞机的薪水。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM