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

MySQL三表关联查询:将相同日期的库存更新与订单记录合并为一行

问题原因

你当前的SQL是先左关联stock_updates表,以库存记录为基准匹配订单,自然会漏掉没有对应库存记录的订单(也就是你缺的2021-06-01那条记录)。

解决方法

我们可以先把两个业务表中所有的商品+日期组合取出来,再分别匹配当天的库存记录和订单记录,就能覆盖「仅库存更新」「仅下单」「两者都有」三种场景:

MySQL 8.0及以上(支持CTE语法)

WITH all_product_dates AS (
    -- 取出两个表中所有存在记录的商品+日期组合
    SELECT product_id, DATE(registered_at) AS record_date FROM stock_updates
    UNION
    SELECT product_id, DATE(ordered_at) AS record_date FROM order_items
),
daily_stock AS (
    -- 按商品+日期聚合库存记录
    SELECT 
        product_id,
        DATE(registered_at) AS record_date,
        MAX(registered_at) AS registered_at
    FROM stock_updates
    GROUP BY product_id, DATE(registered_at)
),
daily_orders AS (
    -- 按商品+日期聚合订单记录
    SELECT 
        product_id,
        DATE(ordered_at) AS record_date,
        MAX(ordered_at) AS ordered_at
    FROM order_items
    GROUP BY product_id, DATE(ordered_at)
)
SELECT 
    apd.product_id,
    ds.registered_at,
    dos.ordered_at
FROM all_product_dates apd
-- 匹配当天库存记录
LEFT JOIN daily_stock ds 
    ON apd.product_id = ds.product_id 
    AND apd.record_date = ds.record_date
-- 匹配当天订单记录
LEFT JOIN daily_orders dos 
    ON apd.product_id = dos.product_id 
    AND apd.record_date = dos.record_date
-- 如果需要过滤掉products表中不存在的商品,加上下面这行即可
-- INNER JOIN products p ON apd.product_id = p.id
ORDER BY apd.record_date;

MySQL 5.x版本(不支持CTE)

SELECT 
    apd.product_id,
    ds.registered_at,
    dos.ordered_at
FROM (
    SELECT product_id, DATE(registered_at) AS record_date FROM stock_updates
    UNION
    SELECT product_id, DATE(ordered_at) AS record_date FROM order_items
) apd
LEFT JOIN (
    SELECT 
        product_id,
        DATE(registered_at) AS record_date,
        MAX(registered_at) AS registered_at
    FROM stock_updates
    GROUP BY product_id, DATE(registered_at)
) ds ON apd.product_id = ds.product_id AND apd.record_date = ds.record_date
LEFT JOIN (
    SELECT 
        product_id,
        DATE(ordered_at) AS record_date,
        MAX(ordered_at) AS ordered_at
    FROM order_items
    GROUP BY product_id, DATE(ordered_at)
) dos ON apd.product_id = dos.product_id AND apd.record_date = dos.record_date
ORDER BY apd.record_date;

注:如果同一天存在多条库存更新/下单记录,你可以根据业务需求修改聚合逻辑,比如用GROUP_CONCAT拼接所有时间,或者取最新/最早的时间即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 19:27:02