SQL实现:按客户统计已配送披萨的变更与无变更数量问询
简洁SQL实现方案
核心思路
无需使用UNION拆分查询,直接通过条件聚合一次性完成两类订单的统计,同时统一处理NULL和空字符串的判断逻辑,避免拆分查询带来的关联错误或重复计算问题。
实现代码
SELECT co.customer_id, COUNT(CASE WHEN (exclusions IS NOT NULL AND exclusions != '') OR (extras IS NOT NULL AND extras != '') THEN 1 END) AS 有变更订单数, COUNT(CASE WHEN (exclusions IS NULL OR exclusions = '') AND (extras IS NULL OR extras = '') THEN 1 END) AS 无变更订单数 FROM customer_orders co JOIN runner_orders ro ON co.order_id = ro.order_id WHERE ro.status = 'completed' -- 需根据实际表中已配送状态值调整,比如部分表用'delivered' GROUP BY co.customer_id;
关键细节说明
- 空值/空串处理:明确判断
exclusions和extras既非NULL也非空字符串时,才算作有变更订单;反之则为无变更订单,覆盖了所有边界情况。 - 条件聚合优势:通过
CASE WHEN在同一次表关联中完成两类统计,比UNION更高效,也避免了多次关联表可能出现的逻辑错误。 - 已配送订单筛选:通过关联
runner_orders并指定状态条件,确保仅统计已完成配送的披萨订单。
分类型展示的替代写法
如果需要将两类结果分两行展示(类似原UNION的需求),可以使用以下写法,同时规避原UNION可能的错误:
SELECT co.customer_id, '有变更' AS 订单类型, COUNT(*) AS 订单数量 FROM customer_orders co JOIN runner_orders ro ON co.order_id = ro.order_id WHERE ro.status = 'completed' AND ((exclusions IS NOT NULL AND exclusions != '') OR (extras IS NOT NULL AND extras != '')) GROUP BY co.customer_id UNION ALL SELECT co.customer_id, '无变更' AS 订单类型, COUNT(*) AS 订单数量 FROM customer_orders co JOIN runner_orders ro ON co.order_id = ro.order_id WHERE ro.status = 'completed' AND ((exclusions IS NULL OR exclusions = '') AND (extras IS NULL OR extras = '')) GROUP BY co.customer_id ORDER BY customer_id, 订单类型;
这里使用
UNION ALL而非UNION,避免自动去重导致的统计偏差,因为同一客户的两类订单是独立统计的。
内容的提问来源于stack exchange,提问作者Ale
相关产品推荐
相关产品推荐

