SQL代码可正常运行但统计数值不正确,请求排查问题
SQL统计数值异常原因排查及修复
核心问题:多表JOIN引发笛卡尔积重复计算
你的SQL同时关联了offline_bookings和bookings两张表,当同一个骑手在2022-10-10当天既有多条离线订单,又有多条在线订单时,两张表的记录会形成笛卡尔积关联——每条离线订单会和每条在线订单匹配一次,导致统计值被重复累加。
举个例子:骑手A当天有2条离线订单、3条在线订单,JOIN后会生成2×3=6条关联记录。此时SUM(offline_bookings.total_price)会把每条离线订单的金额重复计算3次,COUNT(bookings.id)会把每条在线订单数重复统计2次,最终结果远大于实际值。
另外,原SQL的WHERE条件同时过滤两张表的日期,会导致仅当天同时有离线和在线订单的骑手才会出现在结果中,如果骑手只有其中一类订单,会被直接排除,这也是数据缺失的潜在问题。
修复方案:子查询分别统计后再关联
先对离线、在线订单分别按骑手分组统计,再关联骑手表,避免笛卡尔积:
SELECT b.id AS 'Biker ID', b.first_name AS 'Biker Name', -- 用COALESCE处理无对应订单的情况,避免出现NULL COALESCE(ob.offline_revenue, 0) AS 'Offline Revenue', COALESCE(ob.offline_cars, 0) AS 'Offline Cars', COALESCE(ob.extra_service_count, 0) AS 'Extra Service Count', COALESCE(bo.online_cars, 0) AS 'Online Cars', COALESCE(bo.online_revenue, 0) AS 'Online Revenue' FROM bikers b -- 左关联离线订单统计结果 LEFT JOIN ( SELECT biker_id, SUM(total_price) AS offline_revenue, SUM(main_service_count) AS offline_cars, SUM(extra_service_count) AS extra_service_count FROM offline_bookings WHERE `date` = '2022-10-10' AND `status` = TRUE GROUP BY biker_id ) ob ON b.id = ob.biker_id -- 左关联在线订单统计结果 LEFT JOIN ( SELECT biker_id, COUNT(id) AS online_cars, SUM(paid) AS online_revenue FROM bookings WHERE booking_date = '2022-10-10' GROUP BY biker_id ) bo ON b.id = bo.biker_id -- 可选:过滤出至少有一类订单的骑手,若要保留所有骑手可去掉此条件 WHERE ob.biker_id IS NOT NULL OR bo.biker_id IS NOT NULL ORDER BY b.id, b.first_name;
这个方案中,子查询先完成单表的分组统计,再和骑手表关联,彻底避免了笛卡尔积的问题,同时通过LEFT JOIN和COALESCE确保不会丢失只有单一类型订单的骑手数据。
内容的提问来源于stack exchange,提问作者Mohammad Al Mashwakhi
相关产品推荐
相关产品推荐

