having后面只能接聚合函数
因为having的存在本来就是为了解决:where后面不能接聚合函数,这个问题。
与where的异同:
相同之处:
1.作用都是筛选
2.都可以使用比较运算符:in,between and,like等等
不同之处:
1.where用在分组前,having用在分组后。(having对分组后进行筛选)
2.where后面不能跟聚合函数,having后面必须跟聚合函数。
3.having中出现的列,必须出现在select中
力扣刷题:1084. 销售分析III
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-01
至2019-03-31
(含)之间出售的商品。
以 任意顺序 返回结果表。
一开始的思路写出来的答案:
select p.product_id,p.product_name from product p
join sales s on p.product_id=s.product_id
group by p.product_id
having min(s.sale_date)>= "2019-01-01" and max(s.sale_date)<="2019-03-31"
思路:
1.连接两个表
2.根据id分组
3.分组后,每组的最大日期和最小日期在给定的区间内
参考了其他大神的解法:
第一种:
1.连接两个表
2.根据id分组
3.分组内,【日期在第一季度的记录之和】=【该分组内的记录之和】
(当这两个和相等,说明,这个id对应的产品只在第一季度销售)
select p.product_id,p.product_name from product p
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(*)
第二种:
先分析题目条件得到:
1.在第一季度内
2.仅在第一季度内
3.要有售出记录
所以在且仅在第一季度出售,可以用not in 其他季度。
步骤:
1.找到id不在第一季度外出售的id
2.找到id在第一季度出售的id
3.和sales表连接(容易忽略)
不在其他季度,也有可能不在第一季度出售,也就是都没卖过这个产品,所以要和sales表连接,也就是该商品要有售出记录
SQL如下:
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
)
第三种:
先找到符合第一季度出售的id,再找到第一季度外出售的id,如果id在这两个表里面,那么这个id就不是仅在第一季度出售。如果在第一季度外出售,也不符合条件。
1.在第一季度内的id
2.不在第一季度内的id
二者作为一张临时表,该表内所有记录都符合需求。
3.从该临时表找到id并与product表连接,找到name
SQL如下:
select p.product_id,p.product_name from(
select distinct product_id from sales
where sale_date between "2019-01-01" and "2019-03-31"
and product_id not in(
select distinct product_id from sales
where sale_date not between "2019-01-01" and "2019-03-31"
)
)t,product p
where t.product_id=p.product_id
该题SQL架构:
Create table If Not Exists Product (product_id int, product_name varchar(10), unit_price int)
Create table If Not Exists Sales (seller_id int, product_id int, buyer_id int, sale_date date, quantity int, price int)
Truncate table Product
insert into Product (product_id, product_name, unit_price) values ('1', 'S8', '1000')
insert into Product (product_id, product_name, unit_price) values ('2', 'G4', '800')
insert into Product (product_id, product_name, unit_price) values ('3', 'iPhone', '1400')
Truncate table Sales
insert into Sales (seller_id, product_id, buyer_id, sale_date, quantity, price) values ('1', '1', '1', '2019-01-21', '2', '2000')
insert into Sales (seller_id, product_id, buyer_id, sale_date, quantity, price) values ('1', '2', '2', '2019-02-17', '1', '800')
insert into Sales (seller_id, product_id, buyer_id, sale_date, quantity, price) values ('2', '2', '3', '2019-06-02', '1', '800')
insert into Sales (seller_id, product_id, buyer_id, sale_date, quantity, price) values ('3', '3', '4', '2019-05-13', '2', '2800')