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 查询,查询购买了 S8 手机却没有购买 iPhone 的买家。注意这里 S8 和 iPhone 是 Product 表中的产品。
查询结果格式如下图表示:
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 | 1 | 3 | 2019-06-02 | 1 | 800 |
| 3 | 3 | 3 | 2019-05-13 | 2 | 2800 |
+-----------+------------+----------+------------+----------+-------+
Result table:
+-------------+
| buyer_id |
+-------------+
| 1 |
+-------------+
id 为 1 的买家购买了一部 S8,但是却没有购买 iPhone,而 id 为 3 的买家却同时购买了这 2 部手机。
解答
想法是创建购买了S8的临时表 再创建没有购买iphone的临时表 两表连接即可
先选出 S8 iphone的id
select product_id
from Product
where product_name = 'S8';
select product_id
from Product
where product_name = 'iPhone';
选出购买了S8的买家
select buyer_id
from Sales
where product_id = (select product_id
from Product
where product_name = 'S8')
选出没有购买iphone的id
select buyer_id
from Sales
where product_id <> (select product_id
from Product
where product_name = 'iPhone')
两表连接
SELECT tmp.buyer_id AS buyer_id
FROM (SELECT buyer_id
FROM Sales
WHERE product_id = (SELECT product_id
FROM Product
WHERE product_name = 'S8')) tmp
JOIN (SELECT buyer_id
FROM Sales
WHERE product_id <> (SELECT product_id
FROM Product
WHERE product_name = 'iPhone')) tmp2
ON tmp.buyer_id = tmp2.buyer_id

也可以转为集合差的问题 从买了S8的集合中删去买了iphone的集合
select A.buyer_id
from
(
select distinct buyer_id
from Product as P join Sales as S
on(P.product_id = S.product_id and P.product_name ='S8')
) as A
left join
(
select distinct buyer_id
from Product as P join Sales as S
on(P.product_id = S.product_id and P.product_name ='iPhone')
) as B
on(A.buyer_id = B.buyer_id)
where B.buyer_id is NULL
别的解答
先做两表连接
SELECT *
FROM Sales AS S LEFT JOIN Product AS P
ON(P.product_id = S.product_id)

对每个买家统计购买S8和Iphone的数量
SELECT SUM(IF(P.`product_name` = 'S8', 1, 0)), SUM(IF(P.`product_name` = 'iPhone', 1, 0))
FROM Sales AS S
LEFT JOIN Product AS P
ON(P.product_id = S.product_id)
GROUP BY S.`seller_id`

再选出购买S8的数量>0 而购买iPhone数量=0的买家id即可
SELECT S.`buyer_id`
FROM Sales AS S
LEFT JOIN Product AS P
ON(P.product_id = S.product_id)
GROUP BY S.`seller_id`
HAVING SUM(IF(P.`product_name` = 'S8', 1, 0)) > 0 AND SUM(IF(P.`product_name` = 'iPhone', 1, 0)) = 0

网友评论