SQL面试题:查询2019年订单量高于2018年的客户ID
SQL面试题解题思路
表结构说明
涉及的4张表结构如下(已修正原结构中字段名多余空格、重复字段的问题):
Shipments: Shipment_id, Price, Order_id, Ship_date, Delivery_Location, Ship_method, ShipETA Customer: Customer_id, order_id, customer_address, prime_eligible Order: Order_id, Order_Qty, Order_date, Order_location, Item_id, Shipment_id Item: Item_id, Item_description, Item_Location
需求
筛选出2019年订单总数量高于2018年的客户ID。
原参考SQL的问题
给出的参考SQL存在明显逻辑错误,无法得到正确结果:
- WHERE子句只筛选了2019年的订单,统计2018年订单总量的CASE判断永远返回0,只要2019年有订单的客户都会被误命中,完全不符合需求
Order是SQL保留关键字,直接作为表名查询会报错,需要用反引号转义
正确解题步骤
- 关联Customer表和Order表,拿到所有客户的订单明细,WHERE层先过滤掉2018、2019之外的订单,减少无效计算
- 按Customer_id分组,分别聚合计算每个客户2018年和2019年的总订单量
- 在HAVING子句中判断两个年份的总订单量大小,保留2019年更高的客户ID即可
正确SQL示例
SELECT c.Customer_id FROM Customer c INNER JOIN `Order` o ON c.order_id = o.Order_id WHERE YEAR(o.Order_date) IN (2018, 2019) GROUP BY c.Customer_id HAVING SUM(CASE WHEN YEAR(o.Order_date) = 2019 THEN o.Order_Qty ELSE 0 END) > SUM(CASE WHEN YEAR(o.Order_date) = 2018 THEN o.Order_Qty ELSE 0 END)
如果需求要求客户2018年必须有订单,只需要在HAVING里额外加判断:SUM(CASE WHEN YEAR(o.Order_date) = 2018 THEN o.Order_Qty ELSE 0 END) > 0即可。
内容的提问来源于stack exchange,提问作者Razu
相关产品推荐
相关产品推荐

