Ostatnimi czasy potrzebowałem danych z sąsiedniej tabeli przy UPDATE jedngo z pól w bazie danych. Danych do przetworzenia było sporo, więc zwracałem uwagę na wydajność zapytania. Aby zebrać potrzebne informacje, można użyć jednego ze sposobów:
- Zebrać potrzebne dane za pomocą SELECT’a, co sprawiłoby, że zajęta zostanie niepotrzebna pamięć w środowisku PHP podczas przypisania rezultatu do zmiennej.
- Wykonać SET z podzapytaniem, ale potrzebnych mi było kilka kolumn z sąsiedniej tabeli, podzapytanie może zwrócić tylko jedną określoną wartość.
- Wykonać JOIN przy update, czego niestety wówczas nie potrafiłem zrobić.
Kartkując manual nie natrafiłem się w standardowej dokumentacji na nic konkretnego, aż nie spojrzałem na bardzo przydatne komentarze użytkowników. Okazało się, że przy UPDATE można wykonywać dowolne JOIN’y, schemat jest następujący:
UPDATE table JOIN another_table SET ...
W tym momencie mamy do dyspozycji wszystkie pola z dołączonej tabeli. Bardzo przydatne.
Przykład z życia.
Miałem za zadanie odznaczyć typy bukmacherskie na trafione, nietrafione, odwołane z przyczyn odwołania całego meczu piłkarskiego oraz te, które jeszcze nie mogą zostać oznaczone jako trafione lub nie, gdyż mecz się jeszcze nie odbył.
UPDATE typer_tickets_items
LEFT JOIN typer_events ON(event_id = item_event)
SET item_status = (
CASE
WHEN event_status IS NULL THEN NULL # mecz nie zostal rozegrany
WHEN event_status = -1 THEN -1 # mecz anulowany
WHEN event_status = item_bet THEN 1 # typ trafiony
ELSE 0 END # typ nietrafiony
) WHERE item_status IS NULL
Mam nadzieję, że komuś się przyda…
Już się przydało, oby więcej takich wpisów!
Dzień dobry, dopiero zaczynam zabawę z mysql i trafiłem na problem 🙁
mianowicie mam tabele www w której jest kolumna zawierająca pole „enable”(zawartość tego pola jest 1) oraz pole „wygasa”(gdzie wpisana jest wartość wygaśnięcia konta). Jak mogę użyć funkcję update gdy chcę by porównać date z pola „wygasa” i gdy jest ona starsza niż dzisiejszy dzień pole „enable” ma zmienić wartość na 0. Jeżeli data w polu „wygasa” jest większa lub równa niż dzisiejszy dzień to wartość pola „enable” ma pozostawioną wartość 1.
Z góry dziękuje za odpowiedz i pozdrawiam
UPDATE tabela SET enable = 0 WHERE wygasa < "tutaj data w formacie YYYY-MM-DD HH:II:SS". Ale tak się nie robi wyświetlania kontentu po dacie wygasania. Lepiej założyć warunek WHERE przy wyświetlaniu (pobieraniu z bazy), a nie latać cronem co ileś minut, żeby ustalić jakieś pole na 0.
Athlan, [do odpowiedzi na pytanie Anonima]
Mi też wydawałoby się takie rozwiązanie dziwne, ale taki WP (na którym stoi również Twój blog) ma podobne rozwiązanie przy publikacji wpisów. Nie analizowałem tego dokładnie, ale wydaje mi się, że to ma na celu optymalizację wyszukiwania. Podam przykład z bazy precla:
tabela: posts, pola: id, post_date, post_status
1 2010-02-03 19:04:33 publish
2 2010-03-18 18:40:12 future
Ps: fajne zabezpieczenie spamowe, ja zamierzam przetestować puste, niewidoczne pole 🙂
Athlan – dzięki!!!
Krótko i na temat 🙂
Dodam tylko, że przy takich kwerendach lepiej jednak jednoznacznie wskazywać tabele z których pochodzą przetwarzane pola…
W przeciwnym wypadku MySql może nam czasami buczeć, że kwerenda nie jest jednoznaczna (i słusznie)
Jeśli nic nie pomyliłem w twoim przykładzie (bo nie wskazałeś tabel :)) to będzie tak:
UPDATE typer_tickets_items tti
LEFT JOIN typer_events te ON (te.event_id = tti.item_event)
SET tti.item_status = (
CASE
WHEN te.event_status IS NULL THEN NULL # mecz nie zostal rozegrany
WHEN te.event_status = -1 THEN -1 # mecz anulowany
WHEN te.event_status = tti.item_bet THEN 1 # typ trafiony
ELSE 0 END # typ nietrafiony
) WHERE tti.item_status IS NULL
Albo prostszy przykład dla leniwych :p
UPDATE siec_strefy ss
LEFT JOIN tmp_spalanie ts ON ts.strefa = ss.nazwa
SET ss.cieploSpalania = ts.sredniaStrefy
Pozdrawiam
manytanks,
thats much faster than o’racle’s site;)
Dzięki, pomogło!
Mnie również się przydał ten wpis, wielkie dzięki!