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、最新のものである 2 番目の 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

そして、最後の 1 つだけがIS NULL条件を通過し、最後の 1 つが再び残ります。

この作業を行うには不必要に複雑な方法のように見えますが、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

私の分析に基づいて、クエリはの最初の o.order_id または最初のエントリ(に基づく)を抽出しようとしています。ただし、このクエリで使用される結合セマンティックは推奨できません。provider_order_product_status_history.provider_order_product_status_history_idprovider_order_product_status_history

于 2013-11-14T01:22:09.563 に答える
0

どちらの結合も内部種類であり、条件によって結果セットを制限します。「条件1でテーブル2に対応する行があり、同時に条件2でテーブル2の行があるテーブル1の値のみを与える」のようなものです。

于 2013-11-14T01:23:38.170 に答える