Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> zapytanie grupujace + pola z poza GROUP BY
BartT
post
Post #1





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 14.06.2004

Ostrzeżenie: (0%)
-----


Proszę o pomoc w skonstruowaniu (i zrozumieniu jak to się robi) zapytania sql które uzupełni kwerendę agregującą o inne dane na temat rekordów będących wynikiem tej agregacji.
Mam 2 tabele: dystanse (półmaraton, 10km, itd.) oraz wyniki zawodnika na poszczególnych dystansach.
Chcę znaleźć najlepsze wyniki dla każdego z dystansów.
Kwerenda grupująca po dystansach z funkcją agregująca min(czas) musi być oparta na danych z więcej niż 1 tabeli powiązanych relacją LEFT JOIN.
Taka kwerenda daje te najkrótsze czasy (z funkcji min(*) w klauzuli SELECT) oraz pola z klauzuli GROUP BY (w tym wypadku dystans).
Nie potrafię natomiast uzupełnić tego zestawienia o identyfikatory rekordów dla których znaleziono te najkrótsze czasy oraz inne pola z tabeli dowiązanej przez JOIN (tabela dystansów).
Chodzi o to, że jeśli do klauzuli SELECT dodam coś co nie jest ani argumentem funkcji agregującej ani parametrem grupowania z klauzuli GROUP BY to w wynikach pojawia się w tym polu przypadkowa (a w każdym razie błędna) wielkość.

Mam taki kod:
  1. SELECT
  2. `results`.user, `races`.raceTypeId, `raceSelection`.nominalDistance,
  3. min(`results`.time) AS personalBest,
  4. count(*) AS numberOfResults
  5.  
  6. /*
  7. Potrzebne są także dodatkowe poniższe pola:
  8.  
  9. `results`.resultId, (identyfikator rekordu z najkrótszym czasem)
  10. `competitions`.name, (nazwa i data zawodów kiedy w których osiągnięto ten najlepszy wynik)
  11. `competitions`.date
  12.  
  13. ale w ten sposób to nie ma prawa działać :-(
  14. */
  15.  
  16. FROM
  17.  
  18. `results`
  19. LEFT JOIN `races` USING (raceId)
  20. LEFT JOIN `raceSelection` USING (raceSelectionId)
  21. LEFT JOIN `competitions` USING (competitionId)
  22.  
  23. GROUP BY `results`.user, `races`.raceTypeId, `raceSelection`.nominalDistance
  24.  
  25.  


Pozdrawiam
Bart
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
mmmmmmm
post
Post #2





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


Zasada jest prosta:
do grupowania dajesz WSZYSTKIE kolumny z zapytania, przy których nie ma funkcji agregującej.

Jak to zapamiętasz, to NA KAŻDYM SZBD zapytanie pójdzie.
Ale są wyjątki ułatwiające, które oczywiście już nie wszędzie działają:
1. Możesz grupować wg numerów kolumn np. SELECT imie, count(id), nazwisko FROM tabela GROUP BY 1,3 da taki sam wynik jak SELECT imie, count(id), nazwisko FROM tabela GROUP BY imie, nazwisko
2. przy kliku polach z danej tabeli, jeśli w zapytaniu wypisujesz również klucz główny (np. ID), to wystarczy że wg niego pogrupujesz np. SELECT id, imie, nazwisko, COUNT(*) FROM tabela GROUP BY id
3. Nie musisz wypisywać stałych do grupowania np. SELECT imie, nazwisko, 'AKTYWNY' status, Count(*) FROM tabela GROUP BY 1,2 to to samo co SELECT imie, nazwisko, 'AKTYWNY' status, Count(*) FROM tabela GROUP BY 1,2,3

Jeszcze parę uwag:
Do twojego zapytania niepotrzebne są LEFT JOINy -tak mi się wydaje. Bez nich zapytanie dostanie kopa (o ile masz dobre indeksy)
Nie używaj Count(*) zwłaszcza przy LEFT JOINach - może dać ci wyniki, nie takie jakie byś chciał. Lepiej użyj Count(tabela.id)
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 5.10.2025 - 21:04