Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno MySQL - update + join

Toto je zoznam záznamov, ktoré chcem upraviť:

select nakup.id 
from nakup
inner join zakaznik on nakup.zakaznik_id=zakaznik.id 
where zakaznik.skupina_id='1' 

Potrebujem pri týchto záznamoch upraviť toto:

update nakup 
set spracovane_skupina=1 

Toto je výsledok:

update nakup 
set spracovane_skupina='1' 
where
(
  select nakup.id 
  from nakup
  inner join zakaznik on nakup.zakaznik_id=zakaznik.id 
  where zakaznik.skupina_id='1'
)

Dostávam chybovú hlášku:

SQL Error (1093): You can't specify target table 'nakup' for update in FROM clause

Doplňujúce informácie:
- MySQL 5.5.8
- motor tabuľky "nakup" je InnoDB
- motor tabuľky "zakaznik" je MyISAM

Toto som mal ako inšpiráciu:
339622-sql-update

Dúfam, že som dodal všetky potrebné informácie. Chcel by som vás poprosiť o pomoc s týmto SQL príkazom. Tabuľky som pre prehľadnosť premenoval na slovenské, takže, ak tam nájdete nejaký preklep, je to len prepisom na poradňu. V originále mám anglické názvy.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
update nakup set spracovane_skupina='1' where id in ( select nakup.id from nakup inner join zakaznik…
Wikan 09.05.2012 21:59
Wikan
Stále tá istá chybová hláška, ale osobne sa mi to tiež zdá syntakticky správne.
msx. 09.05.2012 22:15
msx.
update nakup set spracovane_skupina='1' where id in ( select nakup.id from nakup inner join zakaznik…
AZOR 09.05.2012 22:23
AZOR
Neviem prečo, ale nenastaví to všetky záznamy, niekde bude chyba. Podmienku pre null tam nemám, pret…
msx. 09.05.2012 22:47
msx.
Opravené: Beriem späť. Zle som to odpísal, tiež to bude fungovať. To jsem rád, imho se to líp čte n…
AZOR 09.05.2012 22:53
AZOR
Teraz ešte taká otázka, že čo sa vykoná skôr? Tento alebo ten druhý príkaz? nový
msx. 09.05.2012 22:56
msx.
Spousta lidí to neví, ale pravda je taková, že typicky* nezáleží na tom jak je to napsané, optimaliz… nový
AZOR 09.05.2012 23:10
AZOR
UPDATE nakup t1 JOIN zakaznik t2 ON t1.id=t2.id SET t1.spracovane_skupina='1' WHERE t2.skupina_id =…
pme 09.05.2012 22:32
pme
Takže toto jediné (* ako som neskôr zistil, nie je to jediné, to horné som len zle odpísal) funguje…
msx. 09.05.2012 22:44
msx.
Nevim jak na MySQL, ale pro MS SQL by to vypadalo takto UPDATE t1 SET t1.spracovane_skupina='1' FRO… poslední
Jan Fiala 10.05.2012 12:54
Jan Fiala

update nakup
set spracovane_skupina='1'
where id in
(
select nakup.id
from nakup
inner join zakaznik on nakup.zakaznik_id=zakaznik.id
where zakaznik.skupina_id='1'
)

Tak to nemusis džjonovat, ne?

update nakup
set spracovane_skupina='1'
where zakaznik_id in
(
select id from zakaznik where skupina_id='1' and id is not null
)

Neviem prečo, ale nenastaví to všetky záznamy, niekde bude chyba. Podmienku pre null tam nemám, pretože záznam s null nemám.

Opravené: Beriem späť. Zle som to odpísal, tiež to bude fungovať.

Opravené: Beriem späť. Zle som to odpísal, tiež to bude fungovať.

To jsem rád, imho se to líp čte než ten inner join..

Spousta lidí to neví, ale pravda je taková, že typicky* nezáleží na tom jak je to napsané, optimalizátor to udělá pořád stejně. Existují sice lidé, kteří na přepisy věří - ale typický přepis implicitně přidá/odstraní nějakou novou informaci pro optimalizátor (například když neudělam join ale dam to do projection jako skalární select muže to vracet stejný výsledek ale dal jsem sql enginu navíc informaci, že pro každý řádek z jedné tabulky muže být jen jeden z druhé, kterou při joinu mít nemusel = tzn stejný výsledek ale nejsou to stejné selecty).

Pokud tam máš primární klíče na id, a zakaznik_id a tedy i (heh dnes jsem na to zrovna narazil s JaFim a myslim ze v tvem postu) not null/unique constraint pak by měli být exekuční plány naprosto stejné. Nezávisle na tom jak jsi to napsal, pokud tam například nemáš ten not null constraint pak jsou to dva uplně jiné příkazy (ačkoliv vzhledem k datum dávají stejný výsledek) a tedy i jiné prováděcí plány a muj odhad (vzhledem k většímu množství informací) by byl že to s tim joinem pak poběží rychleji, jinak imho stejný plán a tedy stejně rychle.

* typicky = sql stroj nemůže při větším počtu tabulek projít všechny kombinace (pro příklad Oracle 10g - 60 000 kombinací, Oracle 11g - jíná strategie 2000 po fragmentech) a tedy pokud to napíšeš jinak při větším počtu tabulek tak budou jinak i exekuční plány, ale to pouze tim že neprohledal celý stavový prostor a tam je pak doslova náhoda, co bude lepší.

Takže toto jediné (* ako som neskôr zistil, nie je to jediné, to horné som len zle odpísal) funguje správne. Akurát je tam malá chybička:

UPDATE nakup t1
JOIN zakaznik t2 ON t1.zakaznik_id=t2.id
SET t1.spracovane_skupina='1'
WHERE t2.skupina_id = '1'

Ďakujem za pomoc.

Zpět do poradny Odpovědět na původní otázku Nahoru