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
?下面的查询不是return飞机和对应的工资吗,还是return所有员工的平均工资不具体到每架飞机?
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
更改 table 的格式,以便使用 GROUP BY A.aid
将指定我们仅对飞机 table 进行分组并留下认证和员工table没有动过?
需要 GROUP BY 才能正确执行聚合(在本例中,取平均值)。
如果您不按任何分组,MySQL 将对您的整个 table 执行此聚合。换句话说,如果您使用上次查询,它将 return 所有航程超过 1000 的飞机的平均工资,不区分是哪架飞机。尝试一下,您将看到这种行为。
但是,如果你在这里使用GROUP BY
子句,你会看到每架个人航程超过1000的飞机的平均值,这就是你想要的.没有它,您将取 所有 架飞机的平均值。
在一些样本数据上尝试这些查询,行为上的差异会变得更加明显。
编辑
关于您最后的几句话:是的,我们没有对认证人员或员工做任何事情 table。退一步说,问题表明每架飞机 。很多时候,如果给您的问题陈述阐明了您需要哪一组项目的结果,那么将其作为分组子句是一个很好的开始。
在SQL中写AVG(...)是一种本能,使用GROUP BY来指定你想要的标准作为定义平均值的组。
如果没有 GROUP BY 子句,它只会对所有 E.salary 进行分组并取平均值。
任何时候您 select 将 AVG、SUM、MAX、MIN 等函数与其他列一起聚合时,您必须按不是聚合函数或常量的所有列进行分组。我能想到的唯一例外是当您使用窗口函数时(MySQL 中不可用)。
在这个例子中,我不清楚为什么 a.aid
不是 select 来自 Temp
的。如果有两架具有相同名称但不同 ID 的飞机,您可能会看到类似...
的结果
aname avg
------ -------
747 100,000
747 110,000
DC10 90,000
...其中两条记录是针对具有相同名称的不同飞机 (747)
这里的小组说平均每架飞机的工资,给你每架飞机的平均工资......因为只包括你找到平均工资的飞机的工资。
我正在努力理解 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
?下面的查询不是return飞机和对应的工资吗,还是return所有员工的平均工资不具体到每架飞机?
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
更改 table 的格式,以便使用 GROUP BY A.aid
将指定我们仅对飞机 table 进行分组并留下认证和员工table没有动过?
需要 GROUP BY 才能正确执行聚合(在本例中,取平均值)。
如果您不按任何分组,MySQL 将对您的整个 table 执行此聚合。换句话说,如果您使用上次查询,它将 return 所有航程超过 1000 的飞机的平均工资,不区分是哪架飞机。尝试一下,您将看到这种行为。
但是,如果你在这里使用GROUP BY
子句,你会看到每架个人航程超过1000的飞机的平均值,这就是你想要的.没有它,您将取 所有 架飞机的平均值。
在一些样本数据上尝试这些查询,行为上的差异会变得更加明显。
编辑
关于您最后的几句话:是的,我们没有对认证人员或员工做任何事情 table。退一步说,问题表明每架飞机 。很多时候,如果给您的问题陈述阐明了您需要哪一组项目的结果,那么将其作为分组子句是一个很好的开始。
在SQL中写AVG(...)是一种本能,使用GROUP BY来指定你想要的标准作为定义平均值的组。 如果没有 GROUP BY 子句,它只会对所有 E.salary 进行分组并取平均值。
任何时候您 select 将 AVG、SUM、MAX、MIN 等函数与其他列一起聚合时,您必须按不是聚合函数或常量的所有列进行分组。我能想到的唯一例外是当您使用窗口函数时(MySQL 中不可用)。
在这个例子中,我不清楚为什么 a.aid
不是 select 来自 Temp
的。如果有两架具有相同名称但不同 ID 的飞机,您可能会看到类似...
aname avg
------ -------
747 100,000
747 110,000
DC10 90,000
...其中两条记录是针对具有相同名称的不同飞机 (747)
这里的小组说平均每架飞机的工资,给你每架飞机的平均工资......因为只包括你找到平均工资的飞机的工资。