2012-05-11 54 views
6

學習SQL,如果這是最基本的,很抱歉。試圖找出以下pseudoish代碼工作UPDATE解決方案:帶有ORDER BY,LIMIT和多個表的UPDATE語法

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

以上更像SELECT語法,但我基本上是試圖在最新排表A的,其中更新單個列值在tableB.username(由$ varName表示)中找到的用戶名將鏈接到其在tableB.id中的ID號,該ID號存在於tableA.user_id中的ID中。

希望這是有道理的。我猜有些JOIN是必要的,但子查詢看起來很麻煩UPDATE。我知道ORDER BYLIMIT在UPDATE中涉及多個表時是不受限制的......但我需要該功能。有沒有解決的辦法?

有點困惑,在此先感謝。

回答

15

解決的辦法是將ORDER BY和LIMIT嵌套在FROM子句中作爲連接的一部分。這讓我們先找到要更新的確切行(ta.id),然後提交更新。

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'; 

帽尖到巴倫·施瓦茨,又名Xaprb,以出色的崗位上這個確切的話題: http://www.xaprb.com/blog/2006/08/10/how-to-use-order-by-and-limit-on-multi-table-updates-in-mysql/

+1

+1回答你自己的問題 –

+0

**注意:**這不適用於臨時表 - 從手冊:'你不能在同一個查詢中多次引用TEMPORARY表.' –

0

您可以使用下面的查詢語法:

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; 

這完美的作品。