2012-05-11 22 views
6

Nauka języka SQL, przepraszam, jeśli to jest elementarne. Próbuje dowiedzieć się działający UPDATE rozwiązania poniższego pseudoish Kod producenta:AKTUALIZACJA Składnia z ORDER BY, LIMIT i wieloma tabelami

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

Powyższe jest bardziej jak SELECT składni, ale jestem po prostu staramy się aktualizować pojedynczą wartość kolumny w najnowszej rzędu z TABLEA, gdzie nazwa użytkownika znaleziona w tableB.username (reprezentowana przez $ varName) jest powiązana z jej numerem identyfikacyjnym w tableB.id, który istnieje jako identyfikator w tableA.user_id.

Mam nadzieję, że ma to sens. Zgaduję, że jakiś rodzaj JOIN jest konieczny, ale podzapytania wydają się kłopotliwe dla UPDATE. Rozumiem, i LIMIT są wyłączone, gdy wiele tabel są zaangażowane w UPDATE ... Ale potrzebuję funkcjonalności. Czy istnieje sposób obejścia tego?

Trochę zagubiony, z góry dzięki.

Odpowiedz

15

Rozwiązaniem jest zagnieżdżanie ORDER BY i LIMIT w klauzuli FROM jako części join. To pozwala znaleźć dokładny wiersz do aktualizacji (ta.id), a następnie zatwierdzić aktualizację.

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 końcówka do Baron Schwartz, a.k.a. Xaprb, za doskonałą post na dokładnie tym temacie: http://www.xaprb.com/blog/2006/08/10/how-to-use-order-by-and-limit-on-multi-table-updates-in-mysql/

+1

+1 za odpowiedź na własne pytanie –

+0

** Uwaga: ** To nie działa dla tabel tymczasowych - od instrukcji: 'Nie można odwołać się do tabeli TYMCZASOWEJ więcej niż jeden raz w tym samym zapytaniu. –

0

Można użyć następującej składni zapytania:

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; 

to działa doskonale.

Powiązane problemy