You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LEFT JOIN中仅计算唯一行并正确求和seller_payout?

问题:如何对唯一的orders行求和避免重复计算?

原查询中seller_payout返回错误值,原因是多表关联导致orders行被重复统计:

SELECT buyer_charges_histories.*,
       count(DISTINCT auction_bids.id) AS opportunities_count,
       count(DISTINCT offers.id) AS offers_count,
       count(DISTINCT orders.id) AS orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 1 THEN orders.id ELSE NULL END) AS pending_orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 3 THEN orders.id ELSE NULL END) AS completed_orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 5 THEN orders.id ELSE NULL END) AS canceled_orders_count,
       sum(CASE WHEN orders.status_id = 3 THEN orders.seller_payout ELSE NULL END) as seller_payout
FROM `buyer_charges_histories`
LEFT JOIN `quotes` ON `quotes`.`buyer_charges_history_id` = `buyer_charges_histories`.`id`
LEFT JOIN `offers` ON `quotes`.`id` = `offers`.`quote_id`
AND `offers`.`draft` = 0
AND (`offers`.`enterprise` = 0
     OR `offers`.`enterprise` IS NULL)
LEFT JOIN `auction_bids` ON `offers`.`auction_id` = `auction_bids`.`auction_id`
LEFT JOIN `orders` ON `offers`.`order_id` = `orders.id`
AND `orders`.`test` IS NULL
WHERE `buyer_charges_histories`.`buyer_id` = 1
  AND `buyer_charges_histories`.`buyer_id` IS NOT NULL
GROUP BY `buyer_charges_histories`.`id`
ORDER BY `buyer_charges_histories`.`id` DESC

通过以下查询已确认正确的seller_payout结果:

select sum(seller_payout) from orders where exists (
    select * from offers where offers.order_id = orders.id and offers.draft = 0 and (offers.enterprise = 0 or offers.enterprise is null) and exists (
        select * from quotes where quotes.id = offers.quote_id and quotes.buyer_charges_history_id = 136
    )
) and test is null and status_id = 3

解决方法

要确保仅对唯一的orders行求和,有两种常用方案:

方案1:先对orders去重再关联

将orders表的关联改为子查询,先筛选出唯一的有效订单记录,避免重复行被带入主查询:

SELECT buyer_charges_histories.*,
       count(DISTINCT auction_bids.id) AS opportunities_count,
       count(DISTINCT offers.id) AS offers_count,
       count(DISTINCT orders.id) AS orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 1 THEN orders.id ELSE NULL END) AS pending_orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 3 THEN orders.id ELSE NULL END) AS completed_orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 5 THEN orders.id ELSE NULL END) AS canceled_orders_count,
       sum(CASE WHEN orders.status_id = 3 THEN orders.seller_payout ELSE NULL END) as seller_payout
FROM `buyer_charges_histories`
LEFT JOIN `quotes` ON `quotes`.`buyer_charges_history_id` = `buyer_charges_histories`.`id`
LEFT JOIN `offers` ON `quotes`.`id` = `offers`.`quote_id`
AND `offers`.`draft` = 0
AND (`offers`.`enterprise` = 0
     OR `offers`.`enterprise` IS NULL)
LEFT JOIN `auction_bids` ON `offers`.`auction_id` = `auction_bids`.`auction_id`
-- 改为关联去重后的orders子查询
LEFT JOIN (
    SELECT id, status_id, seller_payout 
    FROM orders 
    WHERE test IS NULL 
    GROUP BY id, status_id, seller_payout -- 确保每个order只保留一行
) AS orders ON `offers`.`order_id` = `orders`.`id`
WHERE `buyer_charges_histories`.`buyer_id` = 1
  AND `buyer_charges_histories`.`buyer_id` IS NOT NULL
GROUP BY `buyer_charges_histories`.`id`
ORDER BY `buyer_charges_histories`.`id` DESC

方案2:使用SUM结合DISTINCT与唯一标识拼接

如果无法提前去重,可以通过拼接order.id和seller_payout确保每个订单的 payout 只被计算一次,再拆分求和:

SELECT buyer_charges_histories.*,
       count(DISTINCT auction_bids.id) AS opportunities_count,
       count(DISTINCT offers.id) AS offers_count,
       count(DISTINCT orders.id) AS orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 1 THEN orders.id ELSE NULL END) AS pending_orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 3 THEN orders.id ELSE NULL END) AS completed_orders_count,
       count(DISTINCT CASE WHEN orders.status_id = 5 THEN orders.id ELSE NULL END) AS canceled_orders_count,
       -- 拼接order.id和payout,去重后提取数值求和
       sum(DISTINCT CASE WHEN orders.status_id = 3 THEN CAST(SUBSTRING_INDEX(CONCAT(orders.id, '|', orders.seller_payout), '|', -1) AS DECIMAL) ELSE NULL END) as seller_payout
FROM `buyer_charges_histories`
LEFT JOIN `quotes` ON `quotes`.`buyer_charges_history_id` = `buyer_charges_histories`.`id`
LEFT JOIN `offers` ON `quotes`.`id` = `offers`.`quote_id`
AND `offers`.`draft` = 0
AND (`offers`.`enterprise` = 0
     OR `offers`.`enterprise` IS NULL)
LEFT JOIN `auction_bids` ON `offers`.`auction_id` = `auction_bids`.`auction_id`
LEFT JOIN `orders` ON `offers`.`order_id` = `orders.id`
AND `orders`.`test` IS NULL
WHERE `buyer_charges_histories`.`buyer_id` = 1
  AND `buyer_charges_histories`.`buyer_id` IS NOT NULL
GROUP BY `buyer_charges_histories`.`id`
ORDER BY `buyer_charges_histories`.`id` DESC

推荐方案1,逻辑更清晰且性能更优,避免了字符串拼接和类型转换的额外开销。

内容的提问来源于stack exchange,提问作者Axel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:42:41