0

0

SQLGROUPBY怎么配合聚合函数使用_SQLGROUPBY与聚合函数组合用法

看不見的法師

看不見的法師

发布时间:2025-09-13 10:22:01

|

220人浏览过

|

来源于php中文网

原创

GROUP BY按列分组数据,聚合函数对每组计算汇总值;WHERE在分组前筛选行,HAVING在分组后基于聚合结果筛选;NULL值被归为一组,多数聚合函数自动忽略NULL;多列分组时,数据库将所有分组列值相同的行划为一组。

sqlgroupby怎么配合聚合函数使用_sqlgroupby与聚合函数组合用法

SQL中的

GROUP BY
子句与聚合函数是数据分析的黄金搭档,简单来说,它允许你将数据行根据一个或多个列的值进行分组,然后对每个组应用聚合函数(如
COUNT
SUM
AVG
MIN
MAX
),从而计算出每个组的汇总结果。没有它,我们很难从海量数据中提炼出有意义的洞察,比如计算每个部门的员工数量,或者统计每个产品的总销售额。

要深入理解

GROUP BY
与聚合函数的协作,我们需要先搞清楚它们各自的角色。聚合函数天生就是为了处理一组数据并返回一个单一的汇总值。比如,
COUNT(*)
会计算所有行的数量,
SUM(amount)
会计算某一列的总和。但当你需要这些汇总值是基于特定分类时,
GROUP BY
就登场了。

它的基本语法是这样的:

SELECT
    列1,
    聚合函数(列2)
FROM
    表名
WHERE
    条件
GROUP BY
    列1
HAVING
    分组后的条件
ORDER BY
    排序字段;

这里,

GROUP BY 列1
告诉数据库,请把所有
列1
值相同的行归为一组。然后,
SELECT
语句中的聚合函数就会对这些分组后的数据独立执行计算。

举个例子,假设我们有一个

Orders
表,包含
CustomerID
OrderAmount
。如果我们想知道每个客户的总消费金额:

SELECT
    CustomerID,
    SUM(OrderAmount) AS TotalSpent
FROM
    Orders
GROUP BY
    CustomerID;

这条语句会先根据

CustomerID
把所有订单分组,然后对每个
CustomerID
组内的
OrderAmount
求和,最终返回每个客户ID及其对应的总消费。

我个人觉得,理解

GROUP BY
的精髓在于它如何改变了聚合函数的“作用域”。如果没有
GROUP BY
,聚合函数会作用于整个查询结果集(如果
WHERE
有筛选,就是筛选后的结果集),返回一个单一的总计。而有了
GROUP BY
,聚合函数的作用域就缩小到了每一个独立的分组。这种从“全局”到“局部”的视角转换,是数据分析中非常强大且常用的能力。

在使用SQL GROUP BY时,WHERE和HAVING子句有什么不同?

这个问题,我遇到过太多初学者甚至一些有经验的开发者都会搞混。简单来说,

WHERE
HAVING
都是用来筛选数据的,但它们筛选的时机和对象完全不同。

WHERE
子句是在数据被分组之前进行筛选的。它作用于原始的、未分组的行。这意味着你可以在
WHERE
子句中使用原始表中的任何列,即使这些列没有出现在
GROUP BY
SELECT
列表中。它的目的是减少要进行分组的数据量,从而提高效率,并确保只有符合条件的行才会被纳入分组计算。

比如,我们只想统计2023年之后订单的客户总消费:

SELECT
    CustomerID,
    SUM(OrderAmount) AS TotalSpent
FROM
    Orders
WHERE
    OrderDate >= '2023-01-01' -- 在分组前,先筛选出2023年后的订单
GROUP BY
    CustomerID;

这里,

WHERE
子句先剔除了2023年之前的订单,然后再对剩下的订单按客户分组并求和。

HAVING
子句则是在数据被
GROUP BY
分组之后,并且聚合函数计算完成之后,才开始进行筛选的。它作用于每个分组的汇总结果。因此,在
HAVING
子句中,你通常会使用聚合函数的结果进行条件判断,或者使用
GROUP BY
子句中出现的列。你不能在
HAVING
子句中直接引用那些没有被分组且没有被聚合的原始列。

MagickPen
MagickPen

在线AI英语写作助手,像魔术师一样在几秒钟内写出任何东西。

下载

继续上面的例子,如果我们还想找出那些总消费超过1000元的客户:

SELECT
    CustomerID,
    SUM(OrderAmount) AS TotalSpent
FROM
    Orders
WHERE
    OrderDate >= '2023-01-01'
GROUP BY
    CustomerID
HAVING
    SUM(OrderAmount) > 1000; -- 在分组并计算总消费后,再筛选出总消费大于1000的客户

这里,

HAVING SUM(OrderAmount) > 1000
是在每个客户的总消费(
SUM(OrderAmount)
)计算出来之后,再判断是否大于1000。

我个人的经验是,如果你想基于原始行数据进行过滤,用

WHERE
;如果你想基于聚合后的结果进行过滤,用
HAVING
。这个区分不仅是语法上的,更是逻辑上的,理解它能帮你写出更精确、更高效的SQL查询。有时候,我会看到有人尝试在
WHERE
里写
SUM(OrderAmount) > 1000
,这通常会报错,因为
WHERE
还没到聚合函数发挥作用的阶段。

SQL GROUP BY如何处理NULL值以及对聚合结果的影响?

NULL
值在数据库里总是一个有点微妙的存在,
GROUP BY
对它的处理方式也值得我们注意。当你使用
GROUP BY
子句对包含
NULL
值的列进行分组时,所有
NULL
值会被视为相等,并被归为一个单独的分组。这和我们平时在
WHERE
子句中用
IS NULL
来判断
NULL
有点类似,但在分组语境下,
NULL
们是“同类”。

举个例子,假设我们有一个

Employees
表,其中
DepartmentID
列可能包含
NULL
值(比如有些员工还没分配部门)。

SELECT
    DepartmentID,
    COUNT(EmployeeID) AS NumberOfEmployees
FROM
    Employees
GROUP BY
    DepartmentID;

执行这条查询后,你会看到类似这样的结果: | DepartmentID | NumberOfEmployees | |--------------|-------------------| | 101 | 5 | | 102 | 8 | | NULL | 3 |

这里,所有

DepartmentID
NULL
的员工被归到了一个名为
NULL
的组中,并且
COUNT(EmployeeID)
计算出了这个组里有3名员工。这通常是符合我们预期的,因为我们可能需要知道那些“未分配部门”的员工数量。

但是,

NULL
值对聚合函数的影响就更复杂一些,因为它取决于具体的聚合函数。

  • COUNT(column_name)
    : 这个函数会忽略
    NULL
    值。也就是说,它只计算指定列中非
    NULL
    值的行数。如果你想计算包括
    NULL
    值在内的所有行数,应该使用
    COUNT(*)
    COUNT(1)
    • 例如,
      COUNT(DepartmentID)
      会忽略
      DepartmentID
      NULL
      的行,而
      COUNT(*)
      则会计算所有行。
  • SUM()
    AVG()
    MIN()
    MAX()
    : 这些聚合函数在计算时,也会自动忽略
    NULL
    值。它们只对非
    NULL
    值进行计算。
    • 比如,
      AVG(Salary)
      会计算所有有薪水记录的员工的平均薪水,而不会把
      NULL
      薪水的员工纳入计算,也不会把
      NULL
      当作0来处理。这通常是合理的,因为
      NULL
      表示“未知”或“不适用”,而不是0。

所以,在处理

NULL
值时,我通常会特别注意
COUNT()
的行为差异,以及其他聚合函数对
NULL
的默认忽略。如果你的业务逻辑需要将
NULL
视为某个特定值(比如将
NULL
部门视为“未分类”,或者将
NULL
薪水视为0),你可能需要在聚合之前使用
COALESCE()
ISNULL()
等函数来转换
NULL
值。这种预处理能确保聚合结果完全符合你的业务需求,避免因为
NULL
的默认行为导致数据分析的偏差。

在多列上使用SQL GROUP BY时,数据分组逻辑是怎样的?

当我们需要更细粒度的分组时,

GROUP BY
允许我们指定多个列。这时候,分组的逻辑会变得更加层级化,或者说,是组合式的。数据库会把所有在
GROUP BY
子句中指定的列的值都相同的行视为一个组。

想象一下,你有一个

Sales
表,包含
Region
(地区)、
ProductCategory
(产品类别)和
SalesAmount
(销售额)。如果你想知道每个地区每个产品类别的总销售额:

SELECT
    Region,
    ProductCategory,
    SUM(SalesAmount) AS TotalSales
FROM
    Sales
GROUP BY
    Region,
    ProductCategory;

这条查询的执行逻辑是这样的:

  1. 首先,数据库会找到所有
    Region
    ProductCategory
    组合都相同的行。
  2. 例如,所有“华东地区”且“电子产品”的销售记录会形成一个组。
  3. 所有“华东地区”且“家居用品”的销售记录会形成另一个组。
  4. 所有“华北地区”且“电子产品”的销售记录又会形成一个组。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

728

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

328

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1263

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

841

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL索引优化解决方案
MySQL索引优化解决方案

共23课时 | 2.1万人学习

Go 教程
Go 教程

共32课时 | 4.3万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号