目录
一、题目
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 部手机。
二、解决
1、count() 和 if()
思路:
该题关键在于筛选 购买了 S8 手机却没有购买 iPhone 的买家
转化为 某个买家购买S8的次数至少为1,购买iPhone的次数为0
,先用 GROUP BY+COUNT+IF
来统计一个各个买家购买各手机的次数。
代码:
SELECT buyer_id AS 'buyer_id'
FROM Product AS p1
INNER JOIN Sales AS s1
ON p1.product_id = s1.product_id
GROUP BY buyer_id
HAVING SUM(IF(p1.product_name = 'S8', 1, 0)) > 0 AND SUM(IF(p1.product_name = 'iPhone', 1, 0)) = 0
# HAVING COUNT(IF(p1.product_name = 'S8', 1, NULL)) > 0 AND COUNT(IF(p1.product_name = 'iPhone', 1, NULL)) = 0
# HAVING SUM( CASE WHEN p1.product_name = 'S8' THEN 1 ELSE 0 END ) > 0 AND SUM( CASE WHEN p1.product_name = 'iPhone' THEN 1 ELSE 0 END ) = 0
# HAVING COUNT(CASE WHEN p1.product_name = 'S8' THEN 1 ELSE NULL END) > 0 AND COUNT(CASE WHEN p1.product_name = 'iPhone' THEN 1 ELSE NULL END) = 0
2、子查询
思路: 略。
代码:
SELECT DISTINCT buyer_id AS "buyer_id"
FROM
(
SELECT buyer_id,
SUM(IF(product_name = 'S8', 1, 0)) AS s8_cnt,
SUM(IF(product_name = 'iPhone', 1, 0)) AS iphone_cnt
FROM Product AS p1
INNER JOIN Sales s1 ON p1.product_id = s1.product_id
GROUP BY buyer_id
HAVING s8_cnt > 0 AND iphone_cnt = 0
) AS tmp1
;
三、参考
1、mysql
2、使用 count()和if 函数进行筛选