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

如何在SQL查询中排除含指定取消状态码的order_id+item_id组合

排除含取消状态的订单商品组合的SQL实现方法

原SQL查询用于获取未发货(ship_date = 0)且date_in晚于2024-01-01的订单状态更新记录,但存在问题:部分order_id + item_id组合包含状态码140、141的取消记录,这些组合的所有记录都需要被彻底排除。

原查询代码:

SELECT
    oi.order_id, oi.item_id, oi.item_description, ois.status_code, s.status_name, ois.status_date,
    FROM_UNIXTIME(ois.status_date) AS status_date_readable, ois.employee_code, ois.qc_fail, ois.`comment`
FROM
    order_item AS oi
INNER JOIN order_item_status AS ois ON oi.order_id = ois.order_id
INNER JOIN `status` AS s ON ois.status_code = s.status_code
WHERE
    oi.ship_date = 0 AND oi.date_in > UNIX_TIMESTAMP('2024-01-01 00:00:00')
ORDER BY oi.order_id ASC, oi.item_id ASC, ois.status_date ASC;

实现方法

方法一:使用NOT EXISTS子查询

通过子查询检查当前order_id+item_id是否存在取消状态记录,若存在则排除整个组合:

SELECT
    oi.order_id, oi.item_id, oi.item_description, ois.status_code, s.status_name, ois.status_date,
    FROM_UNIXTIME(ois.status_date) AS status_date_readable, ois.employee_code, ois.qc_fail, ois.`comment`
FROM
    order_item AS oi
INNER JOIN order_item_status AS ois ON oi.order_id = ois.order_id AND oi.item_id = ois.item_id
INNER JOIN `status` AS s ON ois.status_code = s.status_code
WHERE
    oi.ship_date = 0 
    AND oi.date_in > UNIX_TIMESTAMP('2024-01-01 00:00:00')
    AND NOT EXISTS (
        SELECT 1
        FROM order_item_status ois_cancel
        WHERE ois_cancel.order_id = oi.order_id
          AND ois_cancel.item_id = oi.item_id
          AND ois_cancel.status_code IN (140, 141)
    )
ORDER BY oi.order_id ASC, oi.item_id ASC, ois.status_date ASC;

注:原查询的order_item与order_item_status关联仅用了order_id,补充item_id关联更严谨,避免错误匹配。

方法二:LEFT JOIN+过滤

通过左连接取消状态记录,筛选出无取消记录的组合:

SELECT
    oi.order_id, oi.item_id, oi.item_description, ois.status_code, s.status_name, ois.status_date,
    FROM_UNIXTIME(ois.status_date) AS status_date_readable, ois.employee_code, ois.qc_fail, ois.`comment`
FROM
    order_item AS oi
INNER JOIN order_item_status AS ois ON oi.order_id = ois.order_id AND oi.item_id = ois.item_id
INNER JOIN `status` AS s ON ois.status_code = s.status_code
LEFT JOIN order_item_status ois_cancel 
    ON ois_cancel.order_id = oi.order_id 
    AND ois_cancel.item_id = oi.item_id 
    AND ois_cancel.status_code IN (140, 141)
WHERE
    oi.ship_date = 0 
    AND oi.date_in > UNIX_TIMESTAMP('2024-01-01 00:00:00')
    AND ois_cancel.order_id IS NULL
ORDER BY oi.order_id ASC, oi.item_id ASC, ois.status_date ASC;

方法三:GROUP BY+HAVING预筛选合法组合

先筛选出无取消状态的order_id+item_id组合,再关联查询:

SELECT
    oi.order_id, oi.item_id, oi.item_description, ois.status_code, s.status_name, ois.status_date,
    FROM_UNIXTIME(ois.status_date) AS status_date_readable, ois.employee_code, ois.qc_fail, ois.`comment`
FROM
    order_item AS oi
INNER JOIN order_item_status AS ois ON oi.order_id = ois.order_id AND oi.item_id = ois.item_id
INNER JOIN `status` AS s ON ois.status_code = s.status_code
INNER JOIN (
    SELECT order_id, item_id
    FROM order_item_status
    GROUP BY order_id, item_id
    HAVING SUM(CASE WHEN status_code IN (140,141) THEN 1 ELSE 0 END) = 0
) valid_combinations ON oi.order_id = valid_combinations.order_id AND oi.item_id = valid_combinations.item_id
WHERE
    oi.ship_date = 0 
    AND oi.date_in > UNIX_TIMESTAMP('2024-01-01 00:00:00')
ORDER BY oi.order_id ASC, oi.item_id ASC, ois.status_date ASC;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:20:06