b.serial
ここでは、 で更新する行ごとに個別の を使用することを想定していますa
。(これは特に述べられていませんが、私には最も可能性が高いと思われます。間違っている場合は、お気軽に私の仮定を修正してください。)
小さな例をセットアップします。各列のデータ型が明確ではなかったため、不明な場合は INT を使用しました。lastused には (DATETIME ではなく) DATE データ型を使用しました。
CREATE TABLE a (`cardnumber` VARCHAR(10) NOT NULL PRIMARY KEY, `position` INT, `serial` INT);
CREATE TABLE b (`serial` INT NOT NULL PRIMARY KEY, lastused DATE);
INSERT INTO a VALUES ('x0000',555,NULL),('x0001',700,123),('a1111',601,NULL),('a2222',602,NULL);
INSERT INTO b VALUES (100,'2012-07-15'),(101,NULL),(102,'2010-01-01'),(103,NULL),(104,NULL);
SELECT * FROM a;
SELECT * FROM b;
指定した条件に基づいて、カード番号が「a1111」と「a2222」の行は更新され、他の 2 つの行は更新されません (位置 <= 600、シリアルは既に割り当てられています)。
UPDATE を実行する前に、まず、更新される行と割り当てられる値を返す SELECT を実行します。それを取得したら、それを複数テーブルの UPDATE ステートメントに変換できます。
SELECT a.cardnumber AS `a.cardnumber`
, a.position AS `a.position`
, a.serial AS `a.serial`
, b.serial AS `b.serial`
, b.lastused AS `b.lastused`
FROM (
SELECT @i := @i + 1 AS i
, aa.*
FROM a aa
JOIN (SELECT @i := 0) ii
WHERE aa.position > 600 /* assuming `position` is numeric datatype */
AND aa.serial IS NULL /* assuming 'blank' represented by NULL */
ORDER BY aa.cardnumber
) ia
JOIN (
SELECT @j := @j + 1 AS j
, bb.serial
, bb.lastused
FROM b bb
JOIN (SELECT @j := 0) jj
WHERE bb.lastused IS NULL
OR bb.lastused < DATE_ADD(NOW(),INTERVAL -30 DAY)
ORDER BY bb.serial
) jb
ON ia.i = jb.j
JOIN a ON a.cardnumber = ia.cardnumber
JOIN b ON b.serial = jb.serial
これを UPDATE に変換するには、 を に置き換え、SELECT ... FROM
新しい値をテーブルに割り当てる句をUPDATE
追加します。SET
UPDATE (
SELECT @i := @i + 1 AS i
, aa.*
FROM a aa
JOIN (SELECT @i := 0) ii
WHERE aa.position > 600
AND aa.serial IS NULL
ORDER BY aa.cardnumber
) ia
JOIN (
SELECT @j := @j + 1 AS j
, bb.serial
, bb.lastused
FROM b bb
JOIN (SELECT @j := 0) jj
WHERE bb.lastused IS NULL
OR bb.lastused < DATE_ADD(NOW(),INTERVAL -30 DAY)
ORDER BY bb.serial
) jb
ON ia.i = jb.j
JOIN a ON a.cardnumber = ia.cardnumber
JOIN b ON b.serial = jb.serial
SET a.serial = b.serial
, b.lastused = DATE(NOW())
-- 4 row(s) affected
インライン ビューのクエリを個別に (ia、jb) 実行して、これらが更新する行を取得していることを確認できます。
ia から a への結合、および jb から b への結合は、主キーの一意のキーで行う必要があります。
ia および jb インライン ビューの目的は、これらの行に割り当てられた連続番号を取得して、それらを互いに照合できるようにすることです。
a
およびへの結合はb
、更新したい元のテーブルの行に戻ります。
serial
(明らかに、が INT でない場合、またはlastused
DATE ではなく DATETIME である場合は、いくつかの調整を行う必要があります。)
しかし、これは、実行したい UPDATE を実行する方法の例です (私が理解している限り)。
注:このアプローチは、サブクエリをサポートする MySQL バージョンで機能します。MySQL 4.0 の場合、これを段階的に実行し、「ia」および「jb」インライン ビュー (サブクエリ) からの結果を実際のテーブルに格納する必要があります。次に、インライン ビューの代わりにクエリでそれらのテーブルを参照します。ii および jj サブクエリを削除して、SELECT @i := 0, @j := 0
これらの変数を参照するクエリを実行する前に別のステートメントに置き換えることができます。