目录
语法
SUM(column_name)
SUM
是一个聚合函数(Aggregate Function),用于计算数字列中值的总和。当你需要对表中的某一列数值进行求和时,SUM
函数就显得非常有用。它通常与 GROUP BY
语句一起使用,以计算每个分组中数值的总和,但也可以单独使用来计算整个列的总和。
SUM
函数只能用于数字列。- 如果
SUM
函数作用于空值(NULL),则这些空值将被忽略,不会计入总和。 - 聚合函数(如
SUM
)经常与GROUP BY
语句一起使用,但也可以在没有GROUP BY
的情况下单独使用,此时它们会计算整个结果集的总和。 - 某些数据库系统(如 MySQL)允许你在没有
FROM
子句的情况下使用SUM
(例如,SELECT SUM(0);
),但这通常不是常见的用法。
SELECT column1, column2, ...
FROM table_name
WHERE condition;
WHERE
子句用于指定过滤条件,以限制从数据库表中检索的数据。当你执行一个查询时,WHERE
子句允许你筛选出满足特定条件的记录。如果记录满足 WHERE
子句中的条件,则这些记录会被包含在查询结果中;如果不满足条件,则这些记录会被排除在外
WHERE
子句是在数据被检索之后但在结果被返回之前应用的。这意味着它不会减少数据库需要处理的数据量,但会限制最终返回给客户端的数据量。- 在使用
WHERE
子句时,确保条件正确无误,以避免返回错误的数据或意外的空结果集。 - 对于大型数据库,合理的
WHERE
子句条件可以显著提高查询性能,因为它允许数据库系统更有效地定位和检索数据。 - 在某些情况下,
WHERE
子句可以与GROUP BY
、HAVING
等子句结合使用,以实现更复杂的查询和数据聚合。然而,WHERE
子句在数据分组之前过滤记录,而HAVING
子句在数据分组之后过滤分组。
SELECT column1, aggregate_function(column2)
FROM table_name
WHERE condition1
GROUP BY column1
HAVING condition2;
HAVING
子句主要用于在聚合查询(如使用COUNT()
、SUM()
、AVG()
等聚合函数的查询)中,根据聚合结果对分组后的数据进行筛选。注意,其与WHERE子句不同,WHERE
子句在数据分组之前对原始数据进行过滤,而HAVING
子句则在数据分组并计算聚合值之后对分组结果进行过滤。
- 必须与
GROUP BY
子句一起使用:在没有GROUP BY
子句的情况下,不能使用HAVING
子句。 - 只能引用聚合函数或
GROUP BY
子句中指定的列:HAVING
子句中的条件不能直接引用表中的其他列,除非这些列也包含在GROUP BY
子句中。 - 可以包含多个条件:
HAVING
子句中的条件可以使用AND
、OR
和NOT
等逻辑运算符进行组合。 - 性能考虑:为了提高查询性能,尽量在
WHERE
子句中使用过滤条件,以减少分组操作的数据量。
需求
表: Products
+------------------+---------+ | Column Name | Type | +------------------+---------+ | product_id | int | | product_name | varchar | | product_category | varchar | +------------------+---------+ product_id 是该表主键(具有唯一值的列)。 该表包含该公司产品的数据。
表: Orders
+---------------+---------+ | Column Name | Type | +---------------+---------+ | product_id | int | | order_date | date | | unit | int | +---------------+---------+ 该表可能包含重复行。 product_id 是表单 Products 的外键(reference 列)。 unit 是在日期 order_date 内下单产品的数目。
写一个解决方案,要求获取在 2020 年 2 月份下单的数量不少于 100 的产品的名字和数目。
返回结果表单的 顺序无要求 。
查询结果的格式如下。
示例
输入: Products 表: +-------------+-----------------------+------------------+ | product_id | product_name | product_category | +-------------+-----------------------+------------------+ | 1 | Leetcode Solutions | Book | | 2 | Jewels of Stringology | Book | | 3 | HP | Laptop | | 4 | Lenovo | Laptop | | 5 | Leetcode Kit | T-shirt | +-------------+-----------------------+------------------+ Orders 表: +--------------+--------------+----------+ | product_id | order_date | unit | +--------------+--------------+----------+ | 1 | 2020-02-05 | 60 | | 1 | 2020-02-10 | 70 | | 2 | 2020-01-18 | 30 | | 2 | 2020-02-11 | 80 | | 3 | 2020-02-17 | 2 | | 3 | 2020-02-24 | 3 | | 4 | 2020-03-01 | 20 | | 4 | 2020-03-04 | 30 | | 4 | 2020-03-04 | 60 | | 5 | 2020-02-25 | 50 | | 5 | 2020-02-27 | 50 | | 5 | 2020-03-01 | 50 | +--------------+--------------+----------+ 输出: +--------------------+---------+ | product_name | unit | +--------------------+---------+ | Leetcode Solutions | 130 | | Leetcode Kit | 100 | +--------------------+---------+ 解释: 2020 年 2 月份下单 product_id = 1 的产品的数目总和为 (60 + 70) = 130 。 2020 年 2 月份下单 product_id = 2 的产品的数目总和为 80 。 2020 年 2 月份下单 product_id = 3 的产品的数目总和为 (2 + 3) = 5 。 2020 年 2 月份 product_id = 4 的产品并没有下单。 2020 年 2 月份下单 product_id = 5 的产品的数目总和为 (50 + 50) = 100 。
分析
写一个解决方案,用于获取产品名和数目
select语句用于选择需要返回的列,其中 product_name 表示产品名称,sum(unit) unit 表示产品销售数量的汇总结果并使用别名 unit 进行标识。from子句用于指定查询所需的数据表,Products 和 Orders 分别表示产品信息表和订单信息表。join关键字表示关联两个数据表,使用 using(product_id) 指定关联条件为两表中的 product_id 字段相等。
因为最终需要产品名称,而Orders表近含产品id,交叉连接可以获取对应id的产品名称,连接条件可以使用P.product_id on O.product_id 或using(product_id)
在 2020 年 2 月份下单的产品
首先是对时间的筛选,考虑where子句
where 子句用于对查询的数据进行筛选,使用 order_date >= '2020-02-01' and order_date < '2020-03-01' 条件来确定订单发生时间在 2020 年 2 月份。where order_date >= '2020-02-01' and order_date < '2020-03-01'
对于类似完整年-月,也可以使用like实现where order_date like '2020-02%'
数量不少于 100 的产品
需要对产品数量进行计数,观察实际案例,同一产品存在多次下单记录,所以首先要对数据按照产品id或产品名称进行分组,group by 子句用于对数据进行分组,按照 product_name 来分组。group by product_id。
随后使用having子句限制条件为不少于100的产品,注意having子句用于对分组后的数据进行过滤,需要在group by 之后,只有当 unit 汇总结果大于等于 100 时,当前分组的数据才被保留。having unit >= 100
代码
select
product_name,
sum(unit) as unit
from Products join Orders using (product_id)
where order_date >= '2020-02-01' and order_date < '2020-03-01'
-- where order_date like '2020-02%'
group by product_id
having unit >= 100