2009-05-27 36 views
11

基本上我需要做這樣的事情的UPDATE嵌套SELECT ....這只是一個例子...但第一次查詢的語法並不在MySQL的MySQL在同一個表

update people set prize = '' 
where prize = 'Gold' and class = (select class from people where id = person_id); 
update people set prize = 'Gold' where id = <id>; 
工作

只有一個人可以在任何課程中獲得金獎。我只知道獲得金獎的人的person_id。

我想在第一個查詢中將任何以前的金獎獲獎者與person_id在同一個類中作爲空白。然後在第二位設置新的金牌得主。

我相信我需要使用某種類型的內部連接,但我不是100%確定的。

如果我可以在一個查詢中完成所有操作,那將會更加智能!

任何人都可以借用建議嗎?

謝謝:)

回答

7
UPDATE people 
SET prize = CASE WHEN id = @lucky THEN 'Gold' ELSE 'Silver' END 
WHERE class = (
     SELECT class 
     FROM people 
     WHERE id = @lucky 
     ) 

這將授予所有用戶提供一個Silver獎,除了@lucky一個誰得到Gold

如果您只需要更新@lucky和前冠軍,發出以下命令:

UPDATE people 
SET prize = CASE WHEN id = @lucky THEN 'Gold' ELSE 'Silver' END 
WHERE id = @lucky 
     OR (class, prize) = 
     (
     SELECT class, 'Gold' 
     FROM people 
     WHERE id = @lucky 
     ) 
+0

,張貼在這個問題這不這樣做。在上面的查詢中只刪除了「金牌」獎項並設置了新的金牌,這樣您就可以在「金牌」或「銀牌」級別上覆蓋每個獎項。例如:如果其中一個人有「銅牌」價格會怎樣? – VVS 2009-05-27 17:04:58

+0

@David Hympohl:好的,你可以通過在查詢結尾附加「WHERE class ='Gold'或id = @lucky」來實現。 – Andomar 2009-05-27 17:33:19

+0

@David:@ op的查詢會爲班級中的每個人設置獎勵。我剛剛用'銀'替換了''''以提高可讀性 – Quassnoi 2009-05-27 17:40:58

0

你肯定可以創建一個存儲過程,需要新的獲獎者的ID作爲參數。

然後,您可以在一行中調用該存儲過程。

我使用MS SQL這裏,但類似於:

CREATE PROC UpdatePrize 
    @newid int 

AS 

UPDATE people 
SET prize = '' 
WHERE prize = 'Gold' 
AND class = (SELECT class 
       FROM people 
       WHERE id = @newid) 

UPDATE people 
SET prize = 'Gold' 
WHERE id = @newid 

GO 
1

如果你是一個單獨的語句後,您可以使用CASE操作?不使用MySQL,但類似於:

UPDATE people 
SET prize = CASE 
       WHEN 'Gold' AND id != @newid THEN '' 
       WHEN '' AND id = @newid THEN 'Gold' 
      END 
WHERE class = ( 
       SELECT class 
       FROM people 
       WHERE id = @newid 
      ) 
0

由於您正在做兩個不同的更新,因此不需要在一個查詢中執行此操作。如果由於其中一個查詢可能失敗而擔心數據不一致,則可以使用事務,並且任何兩個查詢的回滾都會失敗。

您當前的查詢完全可讀且易於理解,而發佈的解決方案遠不易讀。

10

在單個SQL查詢中執行復雜更新並不總是最好的。事實上,運行兩個簡單的查詢可能會更高效。所以一定要對兩個解決方案進行基準測試

MySQL支持多表更新的語法擴展UPDATE。您可以執行JOIN作爲更新的一部分,而不是使用子查詢。

然後你可以使用IF()函數(或CASE)有條件地改變prize值不同的值。

所以,如果你絕對必須使用一個單一的查詢,嘗試這樣的事:

UPDATE people p1 JOIN people p2 
    ON (p1.class = p2.class AND p2.id = <person_id>) 
SET prize = IF(p1.id = <person_id>, 'Gold', '') 
WHERE p1.id = <person_id> OR p1.prize = 'Gold'; 

或者這種替代:

UPDATE people p1 JOIN people p2 
    ON (p1.class = p2.class AND p2.id = <person_id>) 
SET p1.prize = CASE 
    WHEN p1.id = <person_id> THEN 'Gold' 
    WHEN p1.prize = 'Gold' THEN '' 
    ELSE p1.prize -- other cases are left as is 
END CASE;