1

Temat: Jak napisać UPDATE z JOINEM zamiast porównania kluczy?

Witam! To mój pierwszy post na tym forum :-)

Przykład uproszczony. Powiedzmy, że mamy dwie tabelki:
1) produkty (id_produkt, id_kat_produktu, cecha_produktu, ...)
2) kat_produktu (id_kat_produktu, cecha_w_slowniku, ...)
,gdzie pole produkty.id_kat_produktu jest referencją do pola w słowniku kat_produktu.id_kat_produktu

Chcąc zrobić UPDATE na tabeli produkty uzależniony od jakiejś cechy w słowniku kat_produktu (można to zagłębiać dalej, ale pozostańmy przy takim przykładzie) napisałem działający przykład:

update produkty p set
    cecha_produktu= 'Nowa wartość'
from
    kat_produktu kp
where
    p.id_kat_produktu = kp.id_kat_produktu
    and kp.cecha_w_slowniku = 'wartosc_powodujaca_zmiane'

Chciałbym jednak zrobić to samo, ale z użyciem złączenia - tylko nie wiem jak, ponieważ poniższy kod nie zadziałał (świadomie użyłem left joina zamiast inner joina):

update p set
    p.cecha_produktu= 'Nowa wartość'
from
    produkty p
    left join kat_produktu kp on (kp.id_kat_produktu = p.id_kat_produktu)
where
    kp.cecha_w_slowniku = 'wartosc_powodujaca_zmiane'

Pojawił się błąd:

ERROR:  relation "p" does not exist (LINE 1)

To oznacza, że PostgreSQL nie rozumie takiego zapisu. Jak w takim razie napisać UPDATE z JOINEM na podanym powyżej przykładzie?

2

Odp: Jak napisać UPDATE z JOINEM zamiast porównania kluczy?

Ostatnio edytowany przez Rogo (2011-02-12 20:22:26)

3

Odp: Jak napisać UPDATE z JOINEM zamiast porównania kluczy?

Dzięki za podpowiedź. Nie wiem dlaczego, ale rzadko używam operatora IN w zapytaniach.

Sprawdziłem wydajność obu rozwiązań i są bardzo zbliżone, jednak z delikatnym wskazaniem na wariant z użyciem IN i podzapytaniem (w moim przypadku: cost=25.91..108.34 v/s cost=25.91..114.56). Tylko ten zapis taki troszkę nieelegancki smile

4

Odp: Jak napisać UPDATE z JOINEM zamiast porównania kluczy?

Zrób tak

update produkty set
    cecha_produktu= 'Nowa wartość'
from
    produkty p
    left join kat_produktu kp on (kp.id_kat_produktu = p.id_kat_produktu)
where
    kp.cecha_w_slowniku = 'wartosc_powodujaca_zmiane'

5

Odp: Jak napisać UPDATE z JOINEM zamiast porównania kluczy?

@rski
Proponowane przez Ciebie rozwiązanie nie zadziała prawidłowo - wykona się UPDATE dla WSZYSTKICH wierszy w tabeli PRODUKTY, zamiast tylko dla spełniających warunki wejściowe. Nawiasem mówiąc testowałem ten wariant zanim stworzyłem ten wątek. Jeśli ma zadziałać z użyciem JOIN (w PostgreSQL) możemy napisać tak:

update produkty p1 set
    p1.cecha_produktu= 'Nowa wartość'
from
    produkty p2
    left join kat_produktu kp on (kp.id_kat_produktu = p2.id_kat_produktu)
where
    p1.id_produkt = p2.id_produkt
    and kp.cecha_w_slowniku = 'wartosc_powodujaca_zmiane'

Wtedy UPDATE wykona się prawidłowo, jednak to nie jest najlepsze rozwiązanie, ponieważ przewidywana wydajność spada 2 do prawie 5 razy w porównaniu do dwóch wariantów poniżej:

update produkty p set
    cecha_produktu= 'Nowa wartość'
from
    kat_produktu kp
where
    p.id_kat_produktu = kp.id_kat_produktu
    and kp.cecha_w_slowniku = 'wartosc_powodujaca_zmiane'

oraz

update produkty set
    cecha_produktu = 'Nowa wartość'
where id_kat_produktu in (
    select id_kat_produktu
    from kat_produktu
    where cecha_w_slowniku = 'wartosc_powodujaca_zmiane'
)

Ostatnio edytowany przez Januszek (2011-02-16 15:11:52)