sql中group by及having的用法

本文介绍了如何使用SQL语句中的WHERE、GROUP BY及HAVING子句来精确筛选和聚合数据。通过具体的例子展示了不同子句的应用顺序及其对结果的影响。
SELECT AVG(ticket_key) , ticket_title
FROM srweb_ticket_ticket
GROUP BY ticket_title

以上这句是按照投票的标题排序,体现在GROUP BY ticket_title,执行完上序之后得出如下的结果
328 苹果
328 葡萄
327 西瓜

如果加上having条件的话会出现如下的结果,having是出现在group by之后的条件的
SELECT AVG(ticket_key) , ticket_title
FROM srweb_ticket_ticket
GROUP BY ticket_title having AVG(ticket_key)>327

328 苹果
328 葡萄

如果再加上where条件的话会出现下面的结果
SELECT AVG(ticket_key) , ticket_title
FROM srweb_ticket_ticket
where ticket_title not in('葡萄') GROUP BY ticket_title having AVG(ticket_key)>327

328 苹果

通过分析,式子。。首先是执行where条件去掉一些不满足的,之后通过group by按照类型进行分组运算,之后在分组求了数的基础上再用having去掉一些数据
<think>我们正在讨论SQL中的GROUP BYHAVING子句。根据引用内容,我们可以总结如下: 1. GROUP BY用于将数据集划分为若干组,通常与聚合函数(如COUNT, SUM, AVG, MAX, MIN等)一起使用,以对每个组进行统计。 2. HAVING子句用于对分组后的结果进行条件过滤,它作用于组,而不是单个记录。 3. WHERE子句在分组前对记录进行过滤,而HAVING在分组后对组进行过滤。 4. HAVING子句的条件中通常包含聚合函数,而WHERE子句则不能直接使用聚合函数。 引用[1]给出了一个例子:查询每个学生的平均成绩,并筛选出平均成绩大于学号为3的学生的平均成绩的记录。 引用[2]详细说明了Group By的使用,包括与聚合函数的结合、与Order By的区别、字段限制等,并强调了Having与Where的区别。 引用[3]通过一个例子说明HAVING子句的条件是聚合语句,并且执行优先级低于聚合语句(即先执行聚合,再使用HAVING过滤)。 引用[4]解释了GROUP BY是“根据一定规则分组”,并举例说明每个部门的人数统计。 现在,我们用一个具体的例子来说明: 假设有一个学生成绩表(sc),包含字段:学号(sno)、课程号(cno)、成绩(grade)。 问题1:统计每个学生的平均成绩。 ```sql SELECT sno, AVG(grade) AS avg_grade FROM sc GROUP BY sno; ``` 问题2:统计平均成绩大于80分的学生。 ```sql SELECT sno, AVG(grade) AS avg_grade FROM sc GROUP BY sno HAVING AVG(grade) > 80; ``` 问题3:查询平均成绩大于学号为3的学生的平均成绩的学生。 ```sql SELECT sno, AVG(grade) AS avg_grade FROM sc GROUP BY sno HAVING AVG(grade) > (SELECT AVG(grade) FROM sc WHERE sno=3); ``` 注意:在HAVING子句中,我们使用了子查询来获取学号为3的学生的平均成绩。 总结区别: - WHERE:在分组前过滤行,条件中不能使用聚合函数。 - HAVING:在分组后过滤组,条件中通常使用聚合函数。 因此,使用步骤通常是: 1. 使用WHERE过滤不需要的行(如果有条件)。 2. 使用GROUP BY对剩余行分组。 3. 使用HAVING过滤分组。 例如:查询选修了3门以上课程且平均成绩大于80的学生的学号和平均成绩。 ```sql SELECT sno, AVG(grade) AS avg_grade FROM sc GROUP BY sno HAVING COUNT(*) > 3 AND AVG(grade) > 80; ``` 但是,如果我们要先筛选成绩大于60的记录,再分组,则: ```sql SELECT sno, AVG(grade) AS avg_grade FROM sc WHERE grade > 60 -- 先过滤掉不及格的记录 GROUP BY sno HAVING COUNT(*) > 3 AND AVG(grade) > 80; ``` 这样,WHERE子句先过滤掉成绩小于等于60的记录,然后再分组,最后用HAVING过滤分组。 希望这个解释能帮助您理解。 §§相关问题§§ 1. SQLGROUP BYHAVING的执行顺序是怎样的? 2. 在HAVING子句中可以使用哪些聚合函数? 3. 能否在GROUP BY子句中使用多个列进行分组? 4. HAVING子句能否引用SELECT子句中定义的别名? 5. 在WHERE子句中不能使用聚合函数,那么如何实现基于聚合函数的条件过滤?</think>### SQLGROUP BYHAVING用法详解 #### 1. **GROUP BY 核心作用** - **分组统计**:将数据按指定列分组,配合聚合函数进行统计计算 例如统计每个部门的人数: ```sql SELECT DepartmentID AS '部门', COUNT(*) AS '人数' FROM BasicDepartment GROUP BY DepartmentID; -- 按部门分组统计[^4] ``` - **执行顺序**:先排序后分组(`GROUP BY` 隐含排序操作)[^4] - **字段限制**:`SELECT` 中的非聚合字段必须出现在 `GROUP BY` 中 #### 2. **HAVING 核心作用** - **分组后过滤**:对分组结果进行条件筛选(作用于组级别) 例如筛选平均分>80的班级: ```sql SELECT class_id, AVG(score) FROM scores GROUP BY class_id HAVING AVG(score) > 80; -- 分组后过滤[^1] ``` - **聚合条件**:必须使用聚合函数(如 `COUNT()`, `SUM()`, `AVG()`) #### 3. **与WHERE的关键区别** | 特性 | WHERE | HAVING | |--------------|--------------------------------|---------------------------------| | **作用时机** | 分组前过滤(原始数据行) | 分组后过滤(聚合结果组)[^3] | | **聚合函数** | 不可直接使用 | 必须配合聚合函数使用[^2] | | **执行顺序** | 先于 `GROUP BY` | 在 `GROUP BY` 之后执行 | | **性能影响** | 先过滤可减少分组计算量 | 对已分组结果进行二次筛选 | **典型错误示例**: ```sql -- 错误!WHERE不能使用聚合函数 SELECT dept, AVG(salary) FROM employees WHERE AVG(salary) > 5000 -- 非法用法 GROUP BY dept; -- 正确写法 SELECT dept, AVG(salary) FROM employees GROUP BY dept HAVING AVG(salary) > 5000; -- HAVING处理聚合条件[^3] ``` #### 4. **组合使用场景** ```sql -- 统计订单量>100且总金额>10万的客户 SELECT customer_id, COUNT(order_id) AS order_count, SUM(amount) AS total_amount FROM orders WHERE order_date > '2023-01-01' -- 先过滤近期订单 GROUP BY customer_id HAVING COUNT(order_id) > 100 -- 再筛选大客户 AND SUM(amount) > 100000; -- 基于聚合结果过滤[^2] ``` #### 5. **执行顺序解析** ```mermaid graph LR A[FROM] --> B[WHERE] --> C[GROUP BY] --> D[HAVING] --> E[SELECT] ``` 1. 先通过 `WHERE` 过滤原始数据 2. 再通过 `GROUP BY` 分组 3. 最后用 `HAVING` 筛选分组结果[^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值