2011-07-13 33 views
16

Tôi có một bảng 'câu trả lời' với cột số nguyên 'problem_id' được lập chỉ mục, cột số nguyên 'times_chosen' và cột 'tùy chọn' là một varchar. Hiện tại, các giá trị duy nhất cho cột 'tùy chọn' là 'A', 'B', 'C' và 'D', mặc dù những giá trị này có thể mở rộng sau này. Tôi muốn tăng thêm một giá trị 'times_chosen' của nhiều câu trả lời (50-100), khi tôi biết problem_id và tùy chọn của từng câu hỏi.Thực hiện WHERE IN trên nhiều cột trong Postgresql

Vì vậy, tôi cần một truy vấn mà là một cái gì đó như:

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

Đây có phải là có thể?

+2

Nó nên, ít nhất tôi nghĩ rằng nó sẽ trong MySQL và MSSQL. Bạn đã thử chưa? Bạn có thể kiểm tra nó bằng 'SET times_chosen = times_chosen' – Dirk

+0

Oh wow, nó thực sự hoạt động, giống như tôi đã viết nó! Nó thậm chí còn sử dụng chỉ mục! Cảm ơn Dirk - nếu bạn chỉ cần sao chép câu trả lời của bạn dưới đây như là một câu trả lời tôi sẽ rất vui khi chấp nhận nó. – PreciousBodilyFluids

+0

heh, tôi không biết đó là cú pháp hợp lệ. Đó là tiện dụng = D –

Trả lời

8

Nên, ít nhất tôi đã thực hiện nó trước trong các SQL khác.

Bạn đã thử chưa? Bạn có thể thử nghiệm nó với SET times_chosen = times_chosen

+0

Hoạt động tuyệt vời, cảm ơn – Udi

0

Bạn đang có lẽ tìm kiếm cú pháp phong cách

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

. Về cơ bản, bạn sử dụng tablename.rowname để chỉ định trường nào bạn đang tìm kiếm. Để xếp hàng tất cả mọi thứ đúng cách, bạn thêm mệnh đề WHERE mà chắc chắn rằng các khóa chính phù hợp:

...WHERE foo.primarykey = bar.primarykey 

hoặc tương đương. Bạn sẽ làm tốt để tra cứu các tham gia bên trong.

17

Bạn có thể tham gia chống lại một bảng ảo của các loại:

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 

Bạn có thể làm điều gì đó tương tự với UPDATE.

+0

Đẹp và mát mẻ ... –

3

Bạn có thể làm điều này nếu bạn cast dữ liệu vào một mảng đầu tiên:

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

Tuy nhiên, đây sẽ là vô cùng hiệu quả, vì nó không thể sử dụng các chỉ số. Sử dụng JOIN được đề xuất bởi @Frank Farmer là một giải pháp tốt hơn nhiều:

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; 
Các vấn đề liên quan