在 SQL 查询中使用 avg() 函数只返回一行?

Posted

技术标签:

【中文标题】在 SQL 查询中使用 avg() 函数只返回一行?【英文标题】:Using avg() function in SQL query returns only one row? 【发布时间】:2017-03-10 19:41:15 【问题描述】:

我有这个 SQL 查询:

SELECT DISTINCT aname, avg(salary) 
FROM aircraft, certified, employees 
WHERE cruisingrange > 1000 AND ((certified.eid = employees.eid) = (aircraft.aid = certified.aid));

在一列中,我试图显示所有航程超过 1000 英里(航程 > 1000)的飞机的飞机名称(aname)。在另一列中,我试图显示经过认证的飞行员(certified.eid = employees.eid)的平均工资(avg(salary)),他们获得了特别是飞行该飞机的认证(在AND之后的整个条件)。但是,它将所有薪水合并为一个值并返回,因此我只得到一个包含两列一行而不是多行的表(它也只显示一个飞机名称)。

不过,这些 SQL 查询单独工作就很好:

SELECT aname 
FROM aircraft 
WHERE cruisingrange > 1000;

SELECT avg(salary)
FROM employees, certified
WHERE employees.eid = certified.eid;

SELECT DISTINCT aname
FROM aircraft, certified
WHERE certified.aid = aircraft.aid;

如何编写一个查询来完成我应该做的事情?我今天才开始自学 SQL,如果答案很明显,我很抱歉。任何建议表示赞赏。

【问题讨论】:

如果您自学 SQL,您可以选择比 mysql 更标准的数据库。每个数据库都有自己的差异和弱点,但 MySQL 在奇怪的行为方面表现出色,尤其是在分组方面。我推荐 Postgres 或其中一个免费的 SQL Server 版本,以便从正确的起点开始。 @LoztInSpace 我明白了,我会调查的。谢谢:) 【参考方案1】:

您使用的是 MySQL,所以请正确使用GROUP BY

SELECT aname, avg(salary) 
FROM aircraft a JOIN
     certified c
     ON a.aid = c.aid JOIN
     employees e
     ON c.eid = e.eid
WHERE cruisingrange > 1000 
GROUP BY aname;

根据您的查询,您似乎不太了解 SQL。所以让我们从那里开始。这里有一些建议:

从不FROM 子句中使用逗号。 始终使用正确、明确的JOIN 语法。 使用有意义的表别名(缩写)。 限定所有列名(我不能在上面的查询中,因为我不知道这些列来自哪里)。 在了解 SQL 之前不要使用DISTINCT。它对性能有很大影响,有时会做一些意想不到的奇怪事情。

那么,您的查询发生了什么?基本上,考虑这个相关的查询:

SELECT aname, avg(salary) 
FROM aircraft a JOIN
     certified c
     ON a.aid = c.aid JOIN
     employees e
     ON c.eid = e.eid
WHERE cruisingrange > 1000 ;

它返回多少行?好吧 。 . .在大多数数据库中,它将返回 0 行和一个错误。这是一个聚合查询,但 SQL 引擎确实知道如何处理 aname

MySQL 允许这种语法,返回一行(因为它是一个没有GROUP BY 的聚合查询)。 aname 的值取自 indeterminate 行。

因此,当您将DISTINCT 添加到SELECT 时,它不起作用。该查询已经只返回了一行,因此根据定义,它是不同的。

【讨论】:

这对我有很大帮助,谢谢!你说得对,我对 SQL 很陌生,而且很糟糕。因此,我将研究有关联接和分组的知识。

以上是关于在 SQL 查询中使用 avg() 函数只返回一行?的主要内容,如果未能解决你的问题,请参考以下文章

SQL AVG 返回一个 int

8.聚集函数 ---SQL

SQL 在 select 子查询中只返回一行或 null

SQL——连接查询聚合函数开窗函数

使用 AVG 时返回多行

Oracle_SQL 分组与聚合函数