力扣白嫖日记(sql)

前言

练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。

今日题目:

1084.销售分析 III
表:Product

列名 类型
product_id int
product_name varchar
unit_price int

product_id 是该表的主键(具有唯一值的列)。该表的每一行显示每个产品的名称和价格。

表:Sales

列名 类型
seller_id int
product_id int
buyer_id int
sale_date date
quantity int
price int

这个表可能有重复的行。product_id 是 Product 表的外键(reference 列)。该表的每一行包含关于一个销售的一些信息。

编写解决方案,报告2019年春季才售出的产品。即在2019-01-01至2019-03-31(含)之间出售的商品。


我那不值一提的想法:

首先梳理一下表内容,题目给了两张表,第一张表是产品表,记录了产品id,产品名,以及价格,第二张表是销售表,记录了销售id,产品id,购买者id,购买数量以及价格,其中销售表中的产品id和产品表中的产品id是同一值。其次分析需求,需要查询2019年春季才售出的产品(2019-01-01 至 2019-03-31)之间售出的产品。我的第一个想法就是between and。然后做完发现需求是仅仅,意思是只能在这个区间段售出,然后这里就得使用not in了,让筛选的结果不在范围外。
最开是我是这样写的,想着它只要没在范围外面,那肯定就在范围里面了。

select product_id,product_name
from Product 
where product_id not in
(
    select product_id
    from Sales
    where sale_date not between "2019-01-01" and "2019-03-31"
)

但是没想到,有一种情况,就是如果产品根本没有卖出去的话,也不会在范围外面,当然也不会在范围里面,所以我们还需要加个条件,使结果在范围里面。

select product_id,product_name
from Product 
where product_id not in
(
    select product_id
    from Sales
    where sale_date not between "2019-01-01" and "2019-03-31"
)
and product_id in
(
    select product_id
    from Sales
    where sale_date between"2019-01-01" and "2019-03-31"
)

然后我看题解的时候有一种很巧妙的方法,就是对区间内商品总量求和,如果数量小于日期,那么就说商品还在其他时间段被卖出了,如果数量等于日期,就标明商品只在这个时间段卖出。

select p.product_id,p.product_name
from Product p 
left join Sales s 
on p.product_id = s.product_id
group by p.product_id
having sum(s.sale_date between"2019-01-01" and "2019-03-31") = count(s.sale_date)

这里不能使用count的原因,是因为count会把0也计算进去,between and 返回的结果是0和1,使用count的结果就是直接等于count(*)了,这样筛选不出来。


结果:

力扣白嫖日记(sql)_第1张图片


总结:

能运行就行。


你可能感兴趣的:(leetcode,sql,数据库)