Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Skomplikowane zapytanie
Forum PHP.pl > Forum > Bazy danych > MySQL
Kwiatol
Jako, że to mój pierwszy post to na początek się przywitam. Witam winksmiley.jpg

Mam problem, z którym od dłuższego czasu nie mogę sobie poradzić mimo przeglądania forum oraz list dyskusyjnych.

  1. SELECT mecz_statystyki_zaw.zawodnik, zaw.imie, zaw.nazwisko, AVG(mecz_statystyki_zaw.pkt) AS pkt
  2. FROM mecz_statystyki_zaw
  3. INNER JOIN zaw ON mecz_statystyki_zaw.zawodnik=zaw.zawodnik WHERE gral=1 AND rozgrywki_id=1 AND sezon_id=2005 ORDER BY mecz_statystyki_zaw.pkt DESC LIMIT 50


Jak zapewne domyślacie się z kodu, mam bazę zawodników i chcę wyciągnąc listę graczy z najlepszymi średnimi. Zapytanie chodzi "tak sobie" jeżeli użyje klauzuli GROUP BY, ale nie mogę go używać bo nie o takie sortowanie mi chodzi, po drugie, baza wyciąga nie najlepze średnie a po prostu najlepsze jednorazowe wyniki punktowe danego zawodnika.

Chodzi o to by podliczyć wszystkie punkty danego zawodnika z bazy i potem wyciągnąć z tego średnią. Moje zapytanie nie działa w ten sposób po prostu nie umiem robić sumy punktów dla danego gracza, oczywiście można zastosować np. WHERE zawodnik=1 itd., ale wtedy się wyśwetli tylko jeden zawodnik, a ja chcę by było ich więcej winksmiley.jpg

Mam nadzieję, że moje tłumaczenie nie jest zbyt zawiłe. Będę bardzo wdzięczny za wskazówki bo mi już pomysły się skończyły.
bodhi
Mi to ewidentnie podchodzi pod GROUP BY zaw.zawodnik
spenalzo
Podaj jakąś strukture bazy to sie pomyśli tongue.gif
SongoQ
Suma punktow dla danej grupy rekordow:

  1. SELECT SUM(punkty) AS punkty
  2. FROM zawodnik
  3. GROUP BY zadowdnik_id
Kwiatol
Dzięki, już poradziłem sobie z tym problemem. Wygląda to mniej więcej tak:

  1. SELECT mecz_id, imie, nazwisko, zaw.nklub, zespol, zaw.zawodnik, AVG($opcja) AS avg, SUM($opcja) AS sum, COUNT(stats_zaw_id) AS mecz
  2. FROM mecz_statystyki_zaw
  3. LEFT JOIN zaw ON mecz_statystyki_zaw.zawodnik=zaw.zawodnik LEFT JOIN klub ON mecz_statystyki_zaw.druzyna_id=klub.klub WHERE (sezon_id='$sezon' AND rozgrywki_id='1' AND gral='1') GROUP BY 'nazwisko' ORDER BY 'avg' DESC LIMIT 50


Teraz problem jest taki jak w jednym zapytaniu (czy da się w ogóle) pokazywać tych zawodników, którzy rozegrali przynajmniej 10 meczów. Najpierw trzeba policzycz wszystkie mecze z bazy, a później zrobić mecz_id>10. Jeśli ktoś wie jak to zrobić w jednym zapytaniu będę wdzięczny za odpowiedź.
spenalzo
Jest błąd przy GROUP BY, zwróć uwagę na kolorowanie składni:

Masz:
  1. GROUP BY 'nazwisko' ORDER BY 'avg'


powinno być
  1. GROUP BY nazwisko ORDER BY avg


ponieważ są to pola , a nie wartości tekstowe.



Drugi błąd:
  1. SELECT mecz_id, imie, nazwisko, zaw.nklub, zespol, zaw.zawodnik,

To również nie jest źle, ale (dla porządku) powinienieś albo używać aliasów albo pełnych nazw tabel rpzy kolumnach. Teraz może i działa, ale jak kiedyś dodasz jedno pole o tej samej nazwie , to wszystko sie pomiesza i nie dojdziesz gdzie jest błąd tongue.gif


Cytat
Teraz problem jest taki jak w jednym zapytaniu (czy da się w ogóle) pokazywać tych zawodników, którzy rozegrali przynajmniej 10 meczów. Najpierw trzeba policzycz wszystkie mecze z bazy, a później zrobić mecz_id>10. Jeśli ktoś wie jak to zrobić w jednym zapytaniu będę wdzięczny za odpowiedź.

Nie wiem dokładnie o co chodzi (nie napisałeś czy jest to kolumna, wynik funkcji czy coś innego) ale są dwa wyjsćia:

  1. WHERE (....) HAVING mecz_id>10 (...) GROUP...


albo dodać odpowiedni warunek w WHERE.


Btw, ważna uwaga - pamiętaj o używaniu mysql_escape_string i/albo intval, jeżeli musisz przekazywać parametry między stronami.
Kwiatol
dzięki śmiga smile.gif Reszte też poprawiłem, to było robocze co prawda, ale dzięki za uwagi.

  1. GROUP BY zawodnik HAVING COUNT(stats_zaw_id) >= 9 ORDER BY avg DESC LIMIT 50
spenalzo
jeżeli to jest w ten sposób to zamiast:
  1. GROUP BY zawodnik HAVING COUNT(stats_zaw_id) >= 9 ORDER BY avg DESC LIMIT 50


daj:

  1. WHERE (...) AND COUNT(stats_zaw_id) >= 9 GROUP BY zawodnik ORDER BY avg DESC LIMIT 50


Having jest po prostu nieoptymalne.
bodhi
Mam pewne wątpliwości czy to działa tak samo smile.gif
spenalzo
HAVING tylko filtruje rekordy (przy użyciu podanego wyrażenia) uzyskane przy pomocy WHERE, już po ich pobraniu przez zapytanie - dlatego jest to niewydajne.
bodhi
Ale czy count można umieścić w where?
spenalzo
A czemu nie? blink.gif
SongoQ
To ja moze wypowiem sie w sprawie tego posta.
@spenalzo Za przeproszeniem, co za pierdoly wypisujesz questionmark.gif?

Cytat
HAVING tylko filtruje rekordy (przy użyciu podanego wyrażenia) uzyskane przy pomocy WHERE, już po ich pobraniu przez zapytanie - dlatego jest to niewydajne.

NIe prawda having jest warunkiem do agregacji czyli do count, max, sum, min, avg itd.

Cytat
Ale czy count można umieścić w where?

Oczywiscie ze nie.

Cytat
A czemu nie?

Bo to logice zaprzecza. Jak mozesz dac warunek do zbioru rekordow, ktorych jeszcze nie znasz.
spenalzo
Ojejq, no pomyliło mi sie tongue.gif
W sumie nie wiem czemu takiego byka zrobiłem skoro wcześniej dobrze napisałem tongue.gif
SongoQ
Cytat
W sumie nie wiem czemu takiego byka zrobiłem skoro wcześniej dobrze napisałem

No kazdemu moze sie zdazyc. tongue.gif

P.S. Mam nadzieje ze po dlugiej przeriwe na forum, czesciej teraz bedziesz bywal.
spenalzo
[quote=SongoQ,2006-02-01 15:19:00] [QUOTE]P.S. Mam nadzieje ze po dlugiej przeriwe na forum, czesciej teraz bedziesz bywal. [/quote]
Jak sie poziom podforum mysql podniesie winksmiley.jpg Ostatnio brak ciekawych wyzwań, a w jakby nie patrzeć to tutaj sie nauczyłem mysqla tongue.gif

A na serio: bywam częściej Rkingsmiley.png
SongoQ
Cytat
Jak sie poziom podforum mysql podniesie winksmiley.jpg Ostatnio brak ciekawych wyzwań, a w jakby nie patrzeć to tutaj sie nauczyłem mysqla

To juz zalezy od pytajacych. Jesli ktos porusza ciekawsze zagadnienia to oczywiscie dyskusja sie podnosi, ale jest jak jest: pytanie - odpowiedz.
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.