表: 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 的产品的名字和数目。
返回结果表单的 顺序无要求。
查询结果的格式如下。
示例 1:
输入:
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 字段相等。
WHERE 子句用于对查询的数据进行筛选,使用 order_date >= '2020-02-01' and order_date < '2020-03-01' 条件来确定订单发生时间在 2020 年 2 月份。
GROUP BY 子句用于对数据进行分组,按照 product_name 来分组。
HAVING 子句用于对分组后的数据进行过滤,只有当 unit 汇总结果大于等于 100 时,当前分组的数据才被保留。
注意:原本的查询是使用 year(order_date) = '2020' and month(order_date) = '02' 对日期进行筛选,但这种方法会使索引失效,影响查询性能。因此,可以使用 order_date >= '2020-02-01' and order_date < '2020-03-01' 来替代。还可以使用 where order_date like '2020-02%',但是对于大批量数据的查询,这种方式的性能也可能较低。由于先对 SUM(unit) 进行了别名操作,故可以在 HAVING 子句中直接使用该别名 unit 进行条件筛选。
sql
select p.product_name,sum(o.unit) as unit
from Products p join Orders o on p.product_id = o.product_id
where o.order_date>='2020-02-01' and o.order_date< '2020-03-1'
group by p.product_id
having sum(unit) >= 100
mysql 执行顺序 聚合函数 和 having顺序:
在MySQL中,执行顺序通常遵循以下规则:
-
FROM子句:确定数据来源,包括JOIN操作。
-
ON:如果有JOIN操作,则执行ON条件。
-
JOIN:如果有JOIN操作,则连接相关表。
-
WHERE子句:过滤记录。
-
GROUP BY子句:分组记录。
-
聚合函数(如SUM, COUNT, MAX, MIN等):对分组的结果进行计算。
-
HAVING子句:对聚合后的结果进行过滤。
-
SELECT子句:选取特定的列。
-
DISTINCT子句:去除重复数据。
-
ORDER BY子句:排序最终结果。
-
LIMIT子句:限制最终结果的数量。
在这个执行顺序中,聚合函数和HAVING子句的执行顺序是在GROUP BY子句之后,HAVING子句之前。这意味着聚合函数会在数据分组后计算每个组的聚合值,然后HAVING子句会基于这些聚合值来过滤结果集。
下面是一个简单的SQL查询例子,演示了这个执行顺序:
sql
SELECT category, SUM(sales) AS total_sales
FROM products
WHERE date = '2023-01-01'
GROUP BY category
HAVING SUM(sales) > 1000
ORDER BY total_sales DESC;
在这个例子中:
-
从
products
表中选择数据。 -
过滤出2023年1月1日的数据。
-
根据
category
字段分组数据。 -
计算每个
category
的总销售额(使用SUM(sales)
)。 -
过滤掉总销售额小于1000的组。
-
根据总销售额降序排序结果。