SQL关于having用法及与where的区别

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-012019-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')

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