Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Jak uprościć to zapytanie?
Forum PHP.pl > Forum > Przedszkole
SmokAnalog
Cześć,

mam takie oto zapytanie MySQL:

Kod
SELECT `u`.*,
(
    SELECT count(*)
    FROM `payments` AS `p`
    WHERE `p`.`user_id` = `u`.`id`
) AS `payments_count`,
(
    SELECT coalesce(sum(`amount`), 0)
    FROM `payments` AS `p`
    WHERE `p`.`user_id` = `u`.`id`
) AS `payments_total`,
(
    SELECT count(*)
    FROM `orders` AS `o`
    WHERE `o`.`user_id` = `u`.`id`
) AS `orders_count`,
(
    SELECT coalesce(sum(`price`), 0)
    FROM `orders` AS `o`
    WHERE `o`.`user_id` = `u`.`id`
) AS `orders_total`
FROM `users` AS `u`
ORDER BY `u`.`register_date` DESC


Wygląda na skomplikowane, ale to po prostu wybieranie wszystkich rekordów z tabeli `users` i statystyk z połączonych dwóch innych tabel - `payments` i `orders`. Jak można to uprościć/zoptymalizować, żeby nie wyszukiwać po dwa razy z każdej z dołączonych tabel?

Mile widziana podpowiedź z JOIN-ami, bo używam ORM-a i może być problem z podzapytaniami, chociaż nie dam sobie nic uciąć. smile.gif

P.S. Co jest z tym kolorowaniem składni? Wrzucam jako code, bo kolorowanie MySQL jakieś hieroglify mi wyrzuca.
tomi1985
poczytaj o funkcji

  1. INNER JOIN


SmokAnalog
Nie muszę czytać, znam to. Ale nie wiem jak to zastosować w tym przypadku.
Damonsson
Czyli nie znasz.
SmokAnalog
Po pierwsze jak już to left join, a po drugie mądralo powiedz jak pogrupować to na dwie osobne kupki, żeby dla każdej osobno wyliczyć statystyki tongue.gif
Pyton_000
A to nie wystarczy?
  1. SELECT
  2. u.*,
  3. count(p.id) AS payments_count,
  4. coalesce(sum(p.`amount`), 0) AS payments_total,
  5. count(o.id) AS orders_count,
  6. coalesce(sum(o.`price`), 0) AS orders_total
  7. FROM users u
  8. JOIN payments p ON(p.user_id = u.id)
  9. JOIN orders o ON(o.user_id = u.id)
  10. GROUP BY u.id
  11. ORDER BY `u`.`register_date` DESC


PS. Pewnie to bzdura ale nie mam jak przetestować ;P
SmokAnalog
Pyton, dzięki! Zamieniłem JOIN na LEFT JOIN i śmiga tak jak chciałem. Faktycznie to wystarczy, bo przecież JOIN wszystkie kombinacje wytworzy i w niedopasowanych polach będzie NULL, czyli w polach z `orders` zawsze będzie NULL dla `payments` i na odwrót. Proste, zapomniałem o tym.
Pyton_000
JOIN wyświetla tylko relacje które są dopasowane więc nie powinno być NULL, LEFT dodaje NULL jeżeli brak w tabeli dopasowania.
SmokAnalog
Racja. Ale w takim razie JOIN tu nie pasuje, bo znajduje mi tylko tych użytkowników, którzy mają przypisane zarówno zamówienia, jak i płatności. Muszę się pobawić dokładniej tymi JOIN-ami, bo o ile LEFT JOIN dobrze rozumiem, to JOIN na wielu tabelach nadal mnie czasem zaskakuje.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.