我假設這裏要使用一個單獨的b.serial
的每一行中a
更新。(這是不具體說明,但在我看來是最有可能的;請感覺fr ee糾正我的假設,如果它是錯誤的。)
我設置了一個小例子。目前還不清楚每個列的數據類型,所以我在我不確定的情況下使用了INT。我使用DATE數據類型(而不是DATETIME)作爲lastused。
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;
根據你給的條件下,用cardnumbers「a1111」和「a2222」行應該得到更新,與其它兩行不應該(位置< = 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
要轉換到更新,更換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
您可以運行內嵌視圖的查詢seperately(IA,JB),以確認這些得到你想要更新的行。
從ia到a以及從jb到b的連接應該位於主鍵唯一鍵上。
ia和jb內聯視圖的目的是獲取分配給這些行的序號,以便我們可以將它們相互匹配。
加入到a
和b
將返回到原始表中的行,這是我們想要更新的行。
(顯然,如果serial
不是INT,或者lastused
是DATETIME而不是DATE,則需要進行一些調整。)
但是,這是我怎麼會去這樣做你想要做的UPDATE(盡我的理解是一個例子)
注:這種方法適用於支持的MySQL版本子查詢。對於MySQL 4.0,您需要逐步執行此操作,將「ia」和「jb」內聯視圖(子查詢)的結果存儲到實際表中。然後在查詢中引用這些表來代替內聯視圖。在執行引用這些變量的查詢之前,可以刪除ii和jj子查詢,並用單獨的SELECT @i := 0, @j := 0
語句替換。
你可以發佈樣本表數據和預期的輸出嗎? – arunmoezhi 2012-07-26 20:22:34
你能提供一個小的數據集嗎?我所關心的一個問題是,在a.serial和b.serial中會有很多NULL到NULL的值,所以你無法獲得唯一的更新。這會導致問題。 – Shawn 2012-07-26 20:26:04