2009-02-17 114 views
3

想象一下下面的SQL查詢:SQL:與動態列賦值更新語句

UPDATE MYTABLE 
SET COL2 = (SELECT COL2 + 1 FROM (SELECT MAX(COL2) FROM MYTABLE) AS X) 
WHERE ID IN (1,2,3,4,5) 

假設在執行更新之前MAX(COL2)爲1

我的本意是,更新其中ID = 1 COL2被更新爲'max(COL2)+ 1'(即2),並且針對後續更新'MAX(COL2)+1'被重新評估,使得對於ID = 2,COL2 = 3並且ID = 3,COL2 = 4等...

實際情況是,對於所有行(ID = 1,2,3,4,5),COL2的值爲2.

是否有一種智能的方法讓MAX(COL2)+1的值在每次更新時「重新評估」?我意識到這樣做可能會有性能問題,但我很好奇!有沒有更好的選擇(不涉及多個更新語句)?

BTW:櫃面你想知道使用上面的查詢(嵌套的內部表)的語法在這裏看到:SQL : Using the target table in an UPDATE statement in a nested FROM clause

+0

請張貼你現在在桌面上的內容以及你想看到的結果。 – Quassnoi 2009-02-17 12:16:26

回答

10
UPDATE mytable, (
    SELECT @loop := MAX(col1) 
    FROM 
    mytable 
) o 
SET col1 = (@loop := @loop + 1) 

您在此遇到的情況稱爲query stability

沒有查詢可以看到下面的查詢本身所做的更改,或:

UPDATE mytable 
SET col1 = col2 + 1 
WHERE col1 > col2 

永遠不會結束。

-1

在每個插入應該重新評估它;據推測COL2的最大值不會改變。你確定你不想選擇MAX(COL )? 再次讀你的問題,你混淆了插入和更新(現在已修復)的條款,並且我被引發了一個循環。


你試圖一次更新很多記錄,但它的行爲就好像每個單獨更新一樣。這不會像你打算的那樣工作。

您可以創建一個存儲過程來遍歷每個記錄WHERE ID IN(1,2,3,4,5)並單獨更新。或者,由於您只做5行,爲什麼不復制並粘貼語句五次,並將WHERE子句更改爲WHERE ID = 1(以及後續行中的2,3,4,5)。

+0

「除非你的品牌的SQL不喜歡它?」我相信在MySQL中,UPDATE中的嵌套SELECT必須是雙重包裝的。 我認爲您的解決方案將爲更新中的所有5行分配相同的MAX(COL2)值 – Kristen 2009-02-17 12:27:36

+0

顯然,假設原始帖子中的「BTW」鏈接是正確的。 – 2009-02-17 12:39:22

+0

@lc:回答「作爲一個附註,爲什麼要將MAX(COL2)轉換爲臨時表並再次選擇它?」請閱讀完整的帖子(包括最終BTW) – Joel 2009-02-17 12:39:34

0
declare @loop int 
select @loop = 1 

UPDATE MYTABLE 
SET COL1 = @loop, 
    @loop = @loop+1 
WHERE ID IN (1,2,3,4,5) 
0

有有MAX(COL1)的值+1 「重新評估」 在每個插入一個聰明的辦法?

除非你更新的行一個接一個:(

這將在MSSQL工作,不知道有關MySQL,但可能給你一個想法:

DECLARE @Counter int 

SELECT @Counter = MAX(COL2) FROM MYTABLE 

UPDATE MYTABLE 
SET @Counter = @Counter + 1, 
    COL1 = @Counter 
WHERE ID IN (1,2,3,4,5) 

編輯:我認爲SET語句可以在MSSQL中簡化爲:

SET @Counter = COL1 = @Counter + 1 
2

這裏就是我想要做的方式:

SELECT MAX(col2) FROM mytable INTO @max; 

UPDATE mytable 
SET col2 = @max:[email protected]+1 
WHERE id IN (1,2,3,4,5) 
ORDER BY id; 

我測試了在MySQL 5.1.30和它的作品。

我設置了@max變量,因爲我發現@ Quassnoi在笛卡爾產品中使用它的技巧是不必要的,而且不太可讀。

請注意,MySQL在UPDATE語句(這不是標準SQL)中支持ORDER BY,您應該這樣做,以確保值按所需順序更新。否則MySQL保證沒有特定的順序。