0

我试图了解在此查询中加入的目的是什么。

SELECT 
    DISTINCT o.order_id 
FROM 
    `order` o, 
    `order_product` as op 
LEFT JOIN `provider_order_product_status_history` as popsh 
    on op.order_product_id = popsh.order_product_id 
LEFT JOIN  `provider_order_product_status_history` as popsh2 
    ON popsh.order_product_id = popsh2.order_product_id 
        AND popsh.provider_order_product_status_history_id < 
               popsh2.provider_order_product_status_history_id 
WHERE 
    o.order_id = op.order_id 
    AND popsh2.last_updated IS NULL 
LIMIT 10

困扰我的是 provider_order_product_status_history 加入了 2 次,我不确定它的目的。非常感谢有人可以提供帮助

4

3 回答 3

2

这是一种检索最新订单状态的技术。

因为

AND popsh.provider_order_product_status_history_id < popsh2.provider_order_product_status_history_id

AND popsh2.last_updated IS NULL

仅返回那些没有任何更新状态的订单状态。

对于最小集合示例,请考虑以下状态历史表:

id  status order_id last_updated
--------------------------------
1   A      X        1:00
2   B      X        2:00

自加入将导致:

id  status order_id last_updated    id  status order_id last_updated
--------------------------------    --------------------------------
1   A      X        1:00            2   B      X        2:00
2   B      X        2:00                NULL   NULL     NULL

第一行会被IS NULL条件过滤掉,只留下第二个raw,也就是最新的。

对于 3 行情况,自联接结果将是:

id  status order_id last_updated    id  status order_id last_updated
--------------------------------    --------------------------------
1   A      X        1:00            2   B      X        2:00
1   A      X        1:00            3   C      X        3:00
2   B      X        2:00            3   C      X        3:00
3   C      X        3:00                NULL   NULL     NULL

只有最后一个会通过IS NULL条件,再次留下最新的一个。

它看起来像是一种不必要的复杂方式来完成这项工作,但它实际上工作得很好,因为 RDBMS 引擎可以非常有效地进行连接。

顺便说一句,由于查询仅检索 order_id,因此查询没有用。我猜 OP 省略了 select 子句中的其他字段。它应该是这样的SELECT o.order_id, popsh.* FROM ...

于 2013-11-14T01:44:04.993 回答
0

等等,你有一个错误:

SELECT 
    DISTINCT o.order_id 
FROM 
    `order` o, 
    `order_product` as op 
LEFT JOIN `provider_order_product_status_history` as popsh 
    on op.order_product_id = popshs.order_product_id 
  ** YOU HAVE EXCESS 's' HERE     ^
LEFT JOIN  `provider_order_product_status_history` as popsh2 
    ON popsh.order_product_id = popsh2.order_product_id 
        AND popsh.provider_order_product_status_history_id < popsh2.provider_order_product_status_history_id 
WHERE 
    o.order_id = op.order_id 
    AND popsh2.last_updated IS NULL 
LIMIT 10

根据我的分析,查询正在尝试提取. 但是,此查询中使用的连接语义是不可推荐的。provider_order_product_status_history.provider_order_product_status_history_idprovider_order_product_status_history

于 2013-11-14T01:22:09.563 回答
0

两个连接都是内部类型限制条件的结果集。这就像“只给表 1 中的值,这些值在条件 1 上在表 2 中具有相应的行,同时在条件 2 上在表 2 中有一行”。

于 2013-11-14T01:23:38.170 回答