LeetCode SQL 1084. 销售分析III 简单

Posted memcpy0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode SQL 1084. 销售分析III 简单相关的知识,希望对你有一定的参考价值。

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

Table: Product

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| product_id   | int     |
| product_name | varchar |
| unit_price   | int     |
+--------------+---------+
Product_id是该表的主键。
该表的每一行显示每个产品的名称和价格。

Table: Sales

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| seller_id   | int     |
| product_id  | int     |
| buyer_id    | int     |
| sale_date   | date    |
| quantity    | int     |
| price       | int     |
+------ ------+---------+
这个表没有主键,它可以有重复的行。
product_id 是 Product 表的外键。
该表的每一行包含关于一个销售的一些信息。

编写一个SQL查询,报告2019年春季才售出的产品。即2019-01-012019-03-31 (含)之间出售的商品。以 任意顺序 返回结果表。查询结果格式如下所示。

示例 1:
输入:

Product table:
+------------+--------------+------------+
| product_id | product_name | unit_price |
+------------+--------------+------------+
| 1          | S8           | 1000       |
| 2          | G4           | 800        |
| 3          | iPhone       | 1400       |
+------------+--------------+------------+
`Sales` table:
+-----------+------------+----------+------------+----------+-------+
| seller_id | product_id | buyer_id | sale_date  | quantity | price |
+-----------+------------+----------+------------+----------+-------+
| 1         | 1          | 1        | 2019-01-21 | 2        | 2000  |
| 1         | 2          | 2        | 2019-02-17 | 1        | 800   |
| 2         | 2          | 3        | 2019-06-02 | 1        | 800   |
| 3         | 3          | 4        | 2019-05-13 | 2        | 2800  |
+-----------+------------+----------+------------+----------+-------+

输出:

+-------------+--------------+
| product_id  | product_name |
+-------------+--------------+
| 1           | S8           |
+-------------+--------------+

解释:
id为1的产品仅在2019年春季销售。
id为2的产品在2019年春季销售,但也在2019年春季之后销售。
id 3的产品在2019年春季之后销售。
我们只退回产品1,因为它是2019年春季才销售的产品。


解法1 表连接+子查询+ not in

首先,从 Sales 表中找出不在2019-01-01到2019-03-31这段时间销售的产品ID:

select product_id
from Sales
where sale_date < '2019-01-01' or sale_date > '2019-03-31';

然后,对 Product 中的产品,判断其 product_id 是否不属于上者:

select product_id, product_name
from Product
where product_id not in (
    select product_id
    from Sales
    where sale_date < '2019-01-01' or sale_date > '2019-03-31'
);

此外,如果一个产品未曾销售过,那么 Sales 表中就没有它的数据,则 not in 返回的结果恒为真。我们可用表连接来判断该产品是否销售过,如果销售过,那么它将出现在连接后的表中。

select distinct Product.product_id, Product.product_name
from Product, Sales
where Product.product_id = Sales.product_id and Sales.product_id not in (
    select Sales.product_id
    from Sales
    where Sales.sale_date < '2019-01-01' or Sales.sale_date > '2019-03-31'
);

解法2 left join + count 的条件计数

题目要求“在2019-01-01至2019-03-31之间出售的商品”,翻译过来就是“所有售出日期都在这个时间内”,也就是“在这个时间内的订单数量等于该商品的总订单数量”,这样就不难写出如下语句:

select sales.product_id as product_id, product.product_name as product_name
from sales left join product on sales.product_id = product.product_id -- 保留左表为NULL的记录
group by product_id
having count(sale_date between '2019-01-01' and '2019-03-31' or null) = count(*) 

值得注意的是 count 的条件用法。举个例子 count(age > 20 or null) 这个语句,里面 or null 必须加,否则就等价于 count(*) 了,要么就是写作 sum(age > 20) 也可以。因为 age > 20 返回的是 truefalse ,而 counttrue, false 都是会计数一次的,只有NULL不会被计数。所以这个 age > 20 or null 表达的是不大于20就为NULL,这样就不会被 count 计数。相当于没有销售订单的不会被计数。

[LeetCode]1083. 销售分析 II(Mysql,having+if)

题目

编写一个 SQL 查询,查询购买了 S8 手机却没有购买 iPhone 的买家。

题解

使用having + sum+if,而不是自查询。

代码

# Write your MySQL query statement below
select buyer_id 
from Sales s join Product p
on s.product_id = p.product_id
group by buyer_id
having sum(if(product_name=‘S8‘,1,0))>0
and sum(if(product_name=‘iPhone‘,1,0))=0

以上是关于LeetCode SQL 1084. 销售分析III 简单的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode:Database 46.销售分析 II

LeetCode:Database 40.产品销售分析 II

[LeetCode]1083. 销售分析 II(Mysql,having+if)

[LeetCode]1083. 销售分析 II(Mysql,having+if)

LeetCode(数据库)- 销售分析 II

每日SQL打卡​​​​​​​​​​​​​​​DAY 11丨产品销售分析 II难度简单