过滤订单状态与订单历史中最后一个订单状态不匹配的订单

Filter orders that have a mismatch with order state with the last order state in order history

我正在使用 Prestashop,我需要将每个订单的当前状态与最后注册的订单历史记录状态进行比较来验证数据完整性。

订单table:

╔══════════╦═══════════════╦
║ id_order ║ current_state ║
╠══════════╬═══════════════╬
║    1     ║       3       ║ 
║    2     ║       1       ║
║    3     ║       2       ║
║    4     ║       1       ║
╚══════════╩═══════════════╩

order_historytable:

╔══════════════════╦══════════╦════════════════╦═════════════════════╦
║ id_order_history ║ id_order ║ id_order_state ║      date_add       ║
╠══════════════════╬══════════╬════════════════╬═════════════════════╬
║        1         ║     1    ║       1        ║ 2016-08-01 11:00:00 ║
║        2         ║     2    ║       1        ║ 2016-08-02 12:00:00 ║
║        3         ║     1    ║       3        ║ 2016-08-03 13:00:00 ║
║        4         ║     3    ║       1        ║ 2016-08-04 14:00:00 ║
║        5         ║     3    ║       2        ║ 2016-08-05 15:00:00 ║
║        6         ║     2    ║       3        ║ 2016-08-06 16:00:00 ║
║        7         ║     4    ║       1        ║ 2016-08-07 17:00:00 ║
╚══════════════════╩══════════╩════════════════╩═════════════════════╩

(自愿遗漏table是给顺序状态起个名字:1="Paid",2="Confirmed",3="Shipped"…)

通常,current_state 订单必须等于最后一个状态历史条目,但有时不是(在我的示例中,对于订单 #2,current_state = 1 但 id_order_state最后一次历史更新是 2),这就是我想揭示的。

我这样做是为了获取每个最后的订单状态更新:

SELECT o.id_order, o.current_state, h.id_order_state, max(h.date_add)
FROM orders o, order_history h
WHERE o.id_order = h.id_order
GROUP BY o.id_order, o.current_state, h.id_order_state
ORDER BY o.id_order ASC

但这还不够,因为首先我只想要每个订单的最后更新状态:

╔══════════╦═══════════════╦════════════════╦═════════════════════╗
║ id_order ║ current_state ║ id_order_state ║   max(h.date_add)   ║
╠══════════╬═══════════════╬════════════════╬═════════════════════╣
║    1     ║       3       ║       3        ║ 2016-08-03 13:00:00 ║
║    2     ║       1       ║       3        ║ 2016-08-06 16:00:00 ║
║    3     ║       2       ║       2        ║ 2016-08-05 15:00:00 ║
║    4     ║       1       ║       1        ║ 2016-08-07 17:00:00 ║
╚══════════╩═══════════════╩════════════════╩═════════════════════╝

然后使用 WHERE current_state <> id_order_state 添加过滤器以仅显示损坏的数据(如订单 #2):

╔══════════╦═══════════════╦════════════════╦═════════════════════╗
║ id_order ║ current_state ║ id_order_state ║   max(h.date_add)   ║
╠══════════╬═══════════════╬════════════════╬═════════════════════╣
║    2     ║       1       ║       3        ║ 2016-08-06 16:00:00 ║
╚══════════╩═══════════════╩════════════════╩═════════════════════╝

完整的 SQL 请求可以做到这一点吗?

Select 首先使用您已有的 max(h.date_add) 子句将订单历史记录放入临时 table。

然后您可以使用您的查询加入此 WHERE o.id_order = h.id_order

通过首先将其放入临时table(或子查询),您已经消除了多行的问题。然后您可以对订单状态进行比较,这将告诉您哪些不同步。

首先将其视为从历史记录中预过滤您不需要的数据table。

w=12=WILL.y.:w=11=w w=10=sh

Klemart3D 这不是基本的 SQL 查询 :) 抱歉,我没有看到标题是由其他用户编辑的 :),但我猜(我希望 XD)这是满足您需要的查询:

SELECT 
    o.`id_order`, o.`current_state`, h.`id_order_state`, h.`date_add`
FROM 
    `ps_order_history` h INNER JOIN (SELECT `id_order`, MAX(`date_add`) AS maxdateadd FROM `ps_order_history` GROUP BY id_order) laststatus ON (h.`id_order` = laststatus.`id_order` AND h.`date_add` = laststatus.`maxdateadd`)
    INNER JOIN `ps_orders` o ON (o.`id_order` = h.`id_order` AND o.`current_state` <> h.`id_order_state`)
ORDER BY h.`id_order` ASC

我已将标准前缀 ps 添加到表名中。

我找到了这个解决方法,但这里发布的其他一些查询比我的要好:

SELECT o.id_order, o.current_state, h.id_order_state, h.date
FROM ps_orders o
LEFT JOIN (
    SELECT id_order, id_order_state, max(date_add) as date
    FROM ps_order_history
    GROUP BY id_order
    ORDER BY id_order DESC
) h ON o.id_order = h.id_order
WHERE o.current_state <> h.id_order_state 
GROUP BY o.id_order
ORDER BY o.id_order DESC

我已将标准前缀 ps 添加到表名中。

注意:此查询在 Prestashop 的请求 SQL 中不起作用(子查询生成 "Undefined checkedFrom error" 和 PS v1.6.0.14)。