聚合函数,where,having

本文详细讲解了数据库中聚合函数如DISTINCT的排序行为,强调了WHERE和HAVING在SQL查询中的作用差异:WHERE用于预筛选行,HAVING则在分组后过滤。还介绍了使用子查询处理WHERE中的聚合限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

聚合函数

1.在一些数据库系统中,包括旧版本的PostgreSQL, DISTINCT的实现会自动对行进行排序,因此ORDER BY是不必要的。 但是这不是SQL标准所要求的,而且当前的PostgreSQL不保证DISTINCT会导致行被排序。

2.where子句不能使用聚合,例如 SELECT city FROM weather WHERE temp_lo = max(temp_lo); --错误

因为WHERE子句确定了哪些行将包含在聚合计算中。从而得到聚合的结果。 通常情况下,可以使用子查询,SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather); --正确

子查询是一个独立的计算,它计算自己的聚合与外部查询中发生的事情分开。

3.HAVING过滤这些分组的行:SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;

4.WHERE和HAVING之间的根本区别在于:WHERE在计算组和聚合之前选择输入行(因此,它控制哪些行进入聚合计算),而HAVING在计算组和聚合之后选择组行。因此,该WHERE子句不得包含聚合函数;尝试使用聚合来确定哪些行将作为聚合的输入是没有意义的。

另一方面,HAVING子句总是包含聚合函数。(严格来说,你可以写一个HAVING不使用聚合的子句,但它很少有用。在这个阶段可以更有效地使用相同的条件WHERE。)

### SQL 聚合函数 HAVING 子句 使用教程 #### 定义与作用 `HAVING` 子句用于在 `SELECT` 语句中对分组后的数据应用条件表达式。不同于 `WHERE` 子句,后者无法处理聚合函数的结果;而 `HAVING` 则可以基于这些结果施加额外的约束[^1]。 #### 基础语法结构 标准的 `HAVING` 子句使用方式如下: ```sql SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s) HAVING group_condition ORDER BY column_name(s); ``` 此模板展示了如何组合多个关键字以实现复杂的数据检索需求[^3]。 #### 实际案例分析 考虑一个名为 `orders` 的表,其中包含订单详情以及客户ID (`customer_id`) 和总金额 (`total_amount`) 字段。为了找出那些累计消费超过 $500 的顾客及其对应的支出总额,可采用以下查询逻辑: ```sql SELECT customer_id, SUM(total_amount) AS total_spent FROM orders GROUP BY customer_id HAVING SUM(total_amount) > 500; ``` 这段代码先按每位客户的 ID 进行分组统计其所有订单的合计花费,再通过 `HAVING` 来限定只返回满足特定数额门槛以上的记录集合。 #### 结合子查询增强功能 当需要更加精细地控制筛选规则时,可以在 `HAVING` 后面嵌套子查询来进行多层判断。例如,在上述基础上如果还想排除掉最近一年内没有任何新订单活动的老客户,则可以通过增加一层时间维度上的限制达成目标: ```sql SELECT o.customer_id, SUM(o.total_amount) AS total_spent FROM orders o WHERE NOT EXISTS ( SELECT * FROM orders recent_orders WHERE recent_orders.customer_id = o.customer_id AND recent_orders.order_date >= DATEADD(year,-1,GETDATE()) ) GROUP BY o.customer_id HAVING SUM(o.total_amount) > 500; ``` 这里利用了 `NOT EXISTS` 关键字配合内部关联查询的方式实现了对外部主查询的有效补充过滤[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值