UPDATE
2つ(またはそれ以上)のテーブルとを結合することはできませんORDER BY
。
次のような方法で、制限を回避できます。
UPDATE
pipeline_deliveries AS upd
JOIN
( SELECT t.pipeline_deliveryID,
@i := @i+1 AS row_number
FROM
( SELECT @i:=0 ) AS dummy
CROSS JOIN
( SELECT d.pipeline_deliveryID
FROM
pipeline_deliveries AS d
JOIN
pipeline_routesXdeliveryID AS rXd
ON d.pipeline_deliveryID = rXd.pipeline_deliveryID
LEFT JOIN
pipeline_routes AS r
ON rXd.pipeline_routeID = r.pipeline_routeID
WHERE
d.pipelineID = 11
ORDER BY
r.departure_time, d.pipeline_deliveryID
) AS t
) AS tmp
ON tmp.pipeline_deliveryID = upd.pipeline_deliveryID
SET
upd.delivery_number = tmp.row_number ;
上記は、MySQLの2つの機能、ユーザー定義変数と派生テーブル内の順序付けを使用しています。後者は標準SQLではないため、MySQLの機能リリースでうまく機能しない可能性があります(オプティマイザーが、LIMIT
句がない限り、派生テーブル内の順序付けが役に立たないことを理解するのに十分賢い場合)。実際、クエリは最新バージョンのMariaDB(5.3および5.5)でそれを正確に実行します。それはあたかもそこになかったかのように実行されORDER BY
、結果は期待されませんでした。MariaDBサイトで関連する質問を参照してください:GROUPBYトリックが最適化されました。
同じことが、オプティマイザコードを改善するメインストリームMySQLの将来のリリース(おそらく5.6で、誰かがこれをテストしたいと思っていますか?)でも非常によく起こる可能性があります。
したがって、これは標準SQLで作成することをお勧めします。最適なのは、まだ実装されていないウィンドウ関数です。ただし、更新の影響を受ける行の小さなサブセットを処理している限り、自己結合を使用することもできます。これは、効率に関してそれほど悪くはありません。
UPDATE
pipeline_deliveries AS upd
JOIN
( SELECT t1.pipeline_deliveryID
, COUNT(*) AS row_number
FROM
( SELECT d.pipeline_deliveryID
, r.departure_time
FROM
pipeline_deliveries AS d
JOIN
pipeline_routesXdeliveryID AS rXd
ON d.pipeline_deliveryID = rXd.pipeline_deliveryID
LEFT JOIN
pipeline_routes AS r
ON rXd.pipeline_routeID = r.pipeline_routeID
WHERE
d.pipelineID = 11
) AS t1
JOIN
( SELECT d.pipeline_deliveryID
, r.departure_time
FROM
pipeline_deliveries AS d
JOIN
pipeline_routesXdeliveryID AS rXd
ON d.pipeline_deliveryID = rXd.pipeline_deliveryID
LEFT JOIN
pipeline_routes AS r
ON rXd.pipeline_routeID = r.pipeline_routeID
WHERE
d.pipelineID = 11
) AS t2
ON t2.departure_time < t2.departure_time
OR t2.departure_time = t2.departure_time
AND t2.pipeline_deliveryID <= t1.pipeline_deliveryID
OR t1.departure_time IS NULL
AND ( t2.departure_time IS NOT NULL
OR t2.departure_time IS NULL
AND t2.pipeline_deliveryID <= t1.pipeline_deliveryID
)
GROUP BY
t1.pipeline_deliveryID
) AS tmp
ON tmp.pipeline_deliveryID = upd.pipeline_deliveryID
SET
upd.delivery_number = tmp.row_number ;