销售分析 Ⅲ
- 题目如下所示
个人题解
这题简单也简单,不简单也不简单。个人的思考过程如下列 SQL 所示
-
-- 1. 建表 CREATE TABLE 1084_Product( product_id INT, -- 产品id product_name VARCHAR(20), -- 产品名称 unit_price INT, -- 产品价格 PRIMARY KEY(product_id) ); CREATE TABLE 1084_Sales( seller_id INT, product_id INT, buyer_id INT, sale_date DATE, quantity INT, price INT, FOREIGN KEY(product_id) REFERENCES 1084_Product(product_id) ); -- PS:这个表没有主键,**有重复的行** -- 2. 编写一个 SQL 查询,报告 2019年春季 才出售的产品。仅在 2019-01-01 至 2019-03-31 之间出售的商品 -- PS:2019年春季才出售的产品的限制是,不能在其他时间段也出售 SELECT sa.product_id FROM 1084_Sales sa WHERE sa.sale_date BETWEEN '2019-01-01' AND '2019-03-31'; SELECT p.product_id, p.product_name FROM 1084_Product p LEFT JOIN 1084_Sales sa ON p.product_id = sa.product_id WHERE sa.sale_date BETWEEN '2019-01-01' AND '2019-03-31'; -- 上面的 SQL 是错的,没办法保证同一个产品不会在另一个时间段也出售 -- 怎么解决呢? -- 很简单,之前也碰到过一道类似的题目,只要使用 NOT IN,查找在春季之外还有销售的 产品 id 即可 SELECT sa.product_id FROM 1084_Sales sa WHERE sa.sale_date NOT BETWEEN '2019-01-01' AND '2019-03-31'; SELECT p.product_id, p.product_name from 1084_Product p WHERE p.product_id NOT IN (SELECT sa.product_id FROM 1084_Sales sa WHERE sa.sale_date NOT BETWEEN '2019-01-01' AND '2019-03-31'); -- Wow Wow Wow,去官网提交了,发现还有一个问题我这个 SQL 并没有解决 -- 那就是:如果在 Sales 表中没有数据的如何处理?(因为在 Sales 表中没有数据,那么它肯定不是在春季限量销售的产品!!) -- 所以上述子查询还有一点点缺陷,必须保证当前产品存在于 Sales 表 SELECT p.product_id, p.product_name from 1084_Product p WHERE p.product_id NOT IN (SELECT sa.product_id FROM 1084_Sales sa WHERE sa.sale_date NOT BETWEEN '2019-01-01' AND '2019-03-31') AND p.product_id IN (SELECT sa.product_id FROM 1084_Sales sa); -- 在官网的众多题解当中,发现可以使用 GROUP BY 和 min max 的方法来解决这题,感觉像是进城了一样,如下所示 SELECT sa.product_id FROM 1084_Sales sa GROUP BY sa.product_id HAVING MIN(sa.sale_date) >= '2019-01-01' AND MAX(sa.sale_date) <= '2019-03-31'; SELECT p.product_id, p.product_name FROM 1084_Product p WHERE p.product_id IN (SELECT sa.product_id FROM 1084_Sales sa GROUP BY sa.product_id HAVING MIN(sa.sale_date) >= '2019-01-01' AND MAX(sa.sale_date) <= '2019-03-31'); -- 或者外连接 SELECT p.product_id, p.product_name FROM 1084_Product p LEFT JOIN 1084_Sales sa ON p.product_id = sa.product_id GROUP BY p.product_id HAVING MIN(sa.sale_date) >= '2019-01-01' AND MAX(sa.sale_date) <= '2019-03-31'; -- 亦或者 where 连接 SELECT p.product_id, p.product_name FROM 1084_Product p, 1084_Sales sa WHERE p.product_id = sa.product_id GROUP BY p.product_id HAVING MIN(sa.sale_date) >= '2019-01-01' AND MAX(sa.sale_date) <= '2019-03-31';