SQL WHERE 子句中的聚合函数

Posted

技术标签:

【中文标题】SQL WHERE 子句中的聚合函数【英文标题】:Aggregate function in SQL WHERE-Clause 【发布时间】:2011-06-11 23:38:27 【问题描述】:

在大学的一次考试中有一道题;是否可以在SQL WHERE 子句中使用聚合函数。

我一直认为这是不可能的,我也找不到任何例子。但是我的回答被标记为假,现在我想知道在哪些情况下可以在WHERE 中使用聚合函数。此外,如果不可能的话,最好能得到一个链接到描述它的规范。

【问题讨论】:

【参考方案1】:

HAVING 类似于 WHERE 的聚合函数,或者您可以使用子查询。

select EmployeeId, sum(amount)
from Sales
group by Employee
having sum(amount) > 20000

或者

select EmployeeId, sum(amount)
from Sales
group by Employee
where EmployeeId in (
    select max(EmployeeId) from Employees)

【讨论】:

是的,如果我知道的话,这是可能的。但是给出了 WHERE。我认为这是一个定义。 谢谢!正是我需要知道和理解的。赞成票。 谢谢,我打算把我的查询留在作业中,然后我找到了这个……你的回答对我很有帮助 谢谢,这为我节省了很多时间,所有其他来源都没有你所做的那样简单。完美的答案。 必须做什么[从员工中选择 max(EmployeeId)],在第二个示例中与第一个示例 [具有 sum(amount) > 20000]。【参考方案2】:

您还没有提到 DBMS。假设您使用的是 MS SQL-Server,我发现了一条不言自明的 T-SQL 错误消息:

"聚合可能不会出现在 WHERE 子句除非它在一个 包含在 HAVING 子句中的子查询 或选择列表,并且该列是 聚合是外部引用"

http://www.sql-server-performance.com/


还有一个可以在子查询中使用的例子。

对于有 5 个或更多订单的客户,显示所有客户和最小订单(其他订单为 NULL):

SELECT a.lastname
     , a.firstname
     , ( SELECT MIN( o.amount )
         FROM orders o
         WHERE a.customerid = o.customerid
           AND COUNT( a.customerid ) >= 5
        )
        AS smallestOrderAmount
FROM account a
GROUP BY a.customerid
       , a.lastname
       , a.firstname ;

更新。

以上在 SQL-Server 和 mysql 中运行,但它没有返回我预期的结果。下一个更接近。我想这与字段customerid、GROUPed BY 和用于查询-子查询连接的字段在第一种情况下是外部表的PRIMARY KEY 有关,而在第二种情况下则不是。

为拥有 5 个或更多订单的客户显示所有客户 ID 和订单数量(其他订单为 NULL):

SELECT o.customerid
     , ( SELECT COUNT( o.customerid )
         FROM account a
         WHERE a.customerid = o.customerid
           AND COUNT( o.customerid ) >= 5
        )
        AS cnt
FROM orders o
GROUP BY o.customerid ;

【讨论】:

是的,我没有提到 DBMS,因为没有任何指定。它只是说 SQL -_- 我认为这种可能性是在 SQL-92 规范中添加的。不知道各种产品何时添加了该功能。仅使用 MySQL 和 SQL-Server 进行测试显示出略有不同的行为(SQL-Server 更严格,可能更接近规范)。如果其他人可以检查其他 SQL 实现,那将会很有趣。 虽然纯粹主义者不同意,但我工作过的大多数地方都说 SQL 表示 Microsoft SSMS,使用 TSQL @JosephDoggie 如果是 SQL ,请询问 SQL ,这是标准中定义的语言。【参考方案3】:

您不能在 WHERE 子句中直接使用聚合;这就是 HAVING 子句的用途。

您可以在 WHERE 子句中使用包含聚合的子查询。

【讨论】:

我知道它可以作为子查询,但我不确定我是否可以说我可以在 WHERE 中使用聚合函数...我认为这是一个定义。 @n3on:我同意...我认为不可能直接在 WHERE 子句中使用聚合 - 正如我所说。只能将它们用作子查询的一部分 - 在我的书中,这不会算作“在 WHERE 子句中”。如果你给出谨慎的、细致入微的答案,我看不出他们怎么能责怪你。如果这是一个多选题,那你就更接近卡住了。 见蒂姆的回答。这是可能的。【参考方案4】:

更新的查询:

select id from t where id < (select max(id) from t);

它将从表 t 中选择除最后一行之外的所有内容。

【讨论】:

我相信这将取决于 Tim 提到的 DBMS。在标准 SQL 中,您必须将其写为 SELECT id FROM t WHERE id &lt; (SELECT MAX(id) FROM t) 是的,你是对的。我只记得在我早期的数据库教程中,有可能在不使用 TOP、LIMIT 或 ROWNUM 的情况下选择前 5 行。 是的,但是聚合函数在子查询的 select 子句中,而不是在 WHERE 中。而且我认为子查询不能被视为聚合函数。【参考方案5】:
SELECT COUNT( * )   
FROM agents   
HAVING COUNT(*)>3;  

查看更多链接:

http://www.w3resource.com/sql/aggregate-functions/count-having.php#sthash.90csRM4I.dpuf]

http://www.w3resource.com/sql/aggregate-functions/count-having.php

【讨论】:

【参考方案6】:

另一个解决方案是将聚合函数移动到标量用户定义函数

创建你的函数:

CREATE FUNCTION getTotalSalesByProduct(@ProductName VARCHAR(500))
RETURNS INT
AS
BEGIN

DECLARE @TotalAmount INT

SET @TotalAmount = (select SUM(SaleAmount) FROM Sales where Product=@ProductName)

RETURN @TotalAmount

END

在 Where 子句中使用函数

SELECT ProductName, SUM(SaleAmount) AS TotalSales
FROM Sales
WHERE dbo.getTotalSalesByProduct(ProductName)  > 1000
GROUP BY Product

参考资料:

1. 2.

希望能帮助别人。

【讨论】:

【参考方案7】:

如果您在 where 子句中使用聚合函数,则意味着您希望根据该聚合函数过滤数据。就我而言,它是SUM()。我会跳到解决方案。

(select * from(select sum(appqty)summ,oprcod from pckwrk_view group by oprcod)AS asd where summ&gt;500)

    内部查询用于获取需要过滤的结果。 必须为必须过滤掉的聚合函数指定一个 ALIAS 名称,因为外部查询无法访问或识别聚合函数中列的实际名称。 最后,过滤器可以应用于内部查询中列的别名

【讨论】:

以上是关于SQL WHERE 子句中的聚合函数的主要内容,如果未能解决你的问题,请参考以下文章

SQL中的WHERE子句中为啥不允许应用聚集函数呢?请通俗的解释一下或者谈谈自己的见解!

SQL Server中的聚合函数都有哪些?

SQL Server中的聚合函数都有哪些?

SQLite 中 WHERE 子句中的聚合函数

SQL Server报错:选择列表中的列无效,因为该列没有包含在聚合函数或 GROUP BY 子句中

在SQL中的聚合函数