2011-07-13 76 views
16

我有一個索引'problem_id'整數列,一個'times_chosen'整數列和一個varchar選項'列'的答案。目前,'選項'欄的唯一值是'A','B','C'和'D',儘管稍後可能會擴展。當我知道他們每個人的problem_id和選項時,我想增加許多(50-100)答案的'times_chosen'值。在Postgresql的多列做一個WHERE IN

所以我需要一個查詢,是這樣的:

UPDATE answers 
SET times_chosen = times_chosen + 1 
WHERE (problem_id, option) IN ((4509, 'B'), (622, 'C'), (1066, 'D'), (4059, 'A'), (4740, 'A')...) 

這可能嗎?

+2

它應該,至少我認爲它會在MySQL和MSSQL中。你試過了嗎?你可以用'SET times_chosen = times_chosen'來測試它 – Dirk

+0

哦哇,它實際上工作,就像我寫的一樣!它甚至使用索引!謝謝德克 - 如果你只是複製下面的答案作爲答案,我會很樂意接受它。 – PreciousBodilyFluids

+0

嘿,我不知道這是有效的語法。這很方便= D –

回答

8

應該,至少我以前在其他SQLS做到了。

你試過了嗎?你可以用它來測試它SET times_chosen = times_chosen

+0

很好,謝謝 – Udi

0

你可能尋找

SELECT * FROM foo, bar WHERE foo.bob = "NaN" AND bar.alice = "Kentucky"; 

風格的語法。本質上,您使用tablename.rowname來指定您要查找的單個字段。爲了正確排列所有內容,請添加WHERE子句以確保主鍵匹配:

...WHERE foo.primarykey = bar.primarykey 

或類似的。你會很好地查找內部連接。

17

你可以加入對各種各樣的虛擬表:

SELECT * FROM answers 
JOIN (VALUES (4509, 'B'), (622, 'C'), (1066, 'D'), (4059, 'A'), (4740, 'A')) 
    AS t (p,o) 
ON p = problem_id AND o = option 

你可以做UPDATE類似的東西。

+0

不錯,很酷... –

3

你可以做到這一點,如果你投中的數據數組第一:

UPDATE answers 
SET times_chosen = times_chosen + 1 
WHERE ARRAY[problem_id::VARCHAR,option] IN ('{4509,B}', '{622,C}', ...) 

然而,這將是令人難以置信的低效率的,因爲它不能使用索引。使用JOIN通過@Frank農民的建議是一個更好的解決方案:

UPDATE answers a 
SET times_chosen = times_chosen + 1 
FROM (VALUES (4509,'B'), (622,'C') ...) AS x (id,o) 
    WHERE x.id=a.problem_id AND x.o=a.option; 
相關問題