2012-05-11 8 views
6

Học SQL, xin lỗi nếu điều này là thô sơ. Cố gắng tìm ra một giải pháp làm việc UPDATE cho pseudoish-mã sau:CẬP NHẬT Cú pháp với ORDER BY, LIMIT và Nhiều Bảng

UPDATE tableA 
SET tableA.col1 = '$var' 
WHERE tableA.user_id = tableB.id 
AND tableB.username = '$varName' 
ORDER BY tableA.datetime DESC LIMIT 1 

Ở trên là giống như SELECT cú pháp, nhưng tôi về cơ bản cố gắng cập nhật một giá trị cột duy nhất trong hàng mới nhất của tableA, nơi một tên người dùng được tìm thấy trong tableB.username (được đại diện bởi $ varName) được liên kết với số ID của nó trong tableB.id, nó tồn tại dưới dạng id trong tableA.user_id.

Hy vọng điều đó có ý nghĩa. Tôi đoán một số loại JOIN là cần thiết, nhưng truy vấn phụ có vẻ phiền hà cho UPDATE. Tôi hiểu rằng ORDER BYLIMIT không có giới hạn khi nhiều bảng tham gia vào CẬP NHẬT ... Nhưng tôi cần chức năng này. Có cách nào để giái quyết vấn đề này không?

Một chút nhầm lẫn, cảm ơn trước.

Trả lời

15

Giải pháp là lồng ORDER BY và LIMIT trong mệnh đề FROM như là một phần của phép nối. Điều này cho phép bạn tìm chính xác hàng được cập nhật (ta.id) trước, sau đó cam kết cập nhật.

UPDATE tableA AS target 
    INNER JOIN (
     SELECT ta.id 
     FROM tableA AS ta 
     INNER JOIN tableB AS tb ON tb.id = ta.user_id 
     WHERE tb.username = '$varName' 
     ORDER BY ta.datetime DESC 
     LIMIT 1) AS source ON source.id = target.id 
    SET col1 = '$var'; 

Hat tip để Baron Schwartz, còn được gọi là Xaprb, cho bài viết xuất sắc về chủ đề này chính xác: http://www.xaprb.com/blog/2006/08/10/how-to-use-order-by-and-limit-on-multi-table-updates-in-mysql/

+1

+1 để trả lời câu hỏi của riêng bạn –

+0

** Lưu ý: ** Điều này không hoạt động đối với các bảng tạm thời - từ hướng dẫn: 'Bạn không thể tham chiếu đến bảng tạm thời nhiều lần trong cùng một truy vấn.' –

0

Bạn có thể sử dụng cú pháp truy vấn sau đây:

update work_to_do as target 
    inner join (
     select w. client, work_unit 
     from work_to_do as w 
     inner join eligible_client as e on e.client = w.client 
     where processor = 0 
     order by priority desc 
     limit 10 
    ) as source on source.client = target.client 
     and source.work_unit = target.work_unit 
    set processor = @process_id; 

này hoạt động hoàn hảo.