Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Sortowanie wedłu średniej ocen
Forum PHP.pl > Forum > Przedszkole
xamrex
Witam.
Posiadam w bazie tabele z ocenami gier.

Struktura
game_id user ocena
Przykładowe wpisy
1 test 5
1 test 3
2 test 2
3 test 5
3 test 1

Mój kod
  1. $wynik= mysql_query ("SELECT * FROM games_rate ");
  2. while ($rekord = mysql_fetch_array ($wynik)) {
  3. $id = $rekord[0];
  4.  
  5.  
  6. $srednia=mysql_query ("SELECT count(*) as numberrate,SUM(rate) as sumrate FROM games_rate WHERE game_id=$id ");
  7. while ($rekord2 = mysql_fetch_array ($srednia)) {
  8. $sredniawka= round($rekord2[1]/$rekord2[0] ,2);
  9.  
  10. echo "SREDNIA $sredniawka  ";
  11. }
  12.  
  13.  
  14.  
  15. echo "GRA $rekord[0]<br>";
  16. }


Jak wyświetlić gry posortowane według średnich?

Domyślam się, że jednym ze sposobów to wyświetlenie właśnie wszystkich gier wraz z średnimi, dodanie każdego wpisu do tabeli i sortowanie wg średniej, następnie wyświetlenie tego. Jednak nie potrafię tego napisać
xamrex
Nazwa tabeli games_ratePola jakie mam w bazie game_id, user_id, rate
Wrzucając kod do bazy
  1. SELECT game_id, AVG(rate)
  2. FROM games_rate
  3. GROUP BY game_id

dostaje error Nieznana kolumna 'rate' w field list
Ja nie mam tabeli ze średnimi, więc liczę ją dzieląc sumę ocen przez ilość głosów
Wicepsik
A masz kolumnę rate w tabeli ? Człowieku myśl withstupidsmiley.gif
xamrex
Cytat
Nazwa tabeli games Pola jakie mam w bazie game_id, user_id, rate

oczywiście że mam.
Tylko NIE zawiera ona ŚREDNIEJ tylko ocenę
np gra o id 5
ma ocenie 3 i 5
(po prostu dwa wpisy)
średnia (3+5)/2=4

Napisałem takie coś
  1. $wynik= mysql_query ("SELECT * FROM games_rate ");
  2.  
  3. while ($rekord = mysql_fetch_array ($wynik)) {
  4. $id = $rekord[0];
  5.  
  6.  
  7. $srednia=mysql_query ("SELECT count(*) as numberrate,SUM(rate) as sumrate FROM games_rate WHERE game_id=$id ");
  8. while ($rekord2 = mysql_fetch_array ($srednia)) {
  9. $sredniawka= round($rekord2[1]/$rekord2[0] ,2);
  10.  
  11.  
  12.  
  13. $i++;
  14. $nr[$i] = $id;
  15. $avg[$i] = $sredniawka;
  16.  
  17. }
  18.  
  19. }
  20.  
  21.  
  22. for ($e=1; $e<20; $e++)
  23. {$razem[$e] = "srednia $avg[$e]  gra $nr[$e]<br>";}
  24.  
  25.  
  26. sort($razem);
  27. for ($c=0; $c<20; $c++)
  28. {echo $razem[$c];}

Wyjaśniam.
Tworzę tabele nr i avg (zawierającą numer gry pobrany z bazy i wyliczoną średnią)
Następnie łączę te tabele razem ze sobą i sortuje.

Możliwe że jest łatwiejszy sposób, jeśli tak to proszę o podpowiedź.
Napisałem pętle dla c,e <20 ponieważ mam tyle pozycji, w przyszłości ulepszę to by zliczał liczbę pozycji z bazy

Dodaję bazę, jeśli ktoś ma chęci bo rozwiązać to w inny sposób
  1. CREATE TABLE games_rate (
  2. game_id int(11) NOT NULL DEFAULT '0',
  3. user_id int(11) NOT NULL DEFAULT '0',
  4. rate int(11) NOT NULL DEFAULT '0',
  5. PRIMARY KEY (game_id,user_id)
  6. ) ;
  7.  
  8.  
  9. INSERT INTO games_rate VALUES (280, 2, 3);
  10. INSERT INTO games_rate VALUES (17, 457, 4);
  11. INSERT INTO games_rate VALUES (280, 457, 2);
  12. INSERT INTO games_rate VALUES (280, 568, 0);
  13. INSERT INTO games_rate VALUES (280, 1720, 0);
  14. INSERT INTO games_rate VALUES (280, 1813, 0);
  15. INSERT INTO games_rate VALUES (280, 1873, 5);
  16. INSERT INTO games_rate VALUES (280, 1918, 5);
  17. INSERT INTO games_rate VALUES (280, 1931, 3);
  18. INSERT INTO games_rate VALUES (734, 2, 3);
  19. INSERT INTO games_rate VALUES (735, 457, 1);
  20. INSERT INTO games_rate VALUES (735, 2, 5);
  21. INSERT INTO games_rate VALUES (280, 1965, 3);
  22. INSERT INTO games_rate VALUES (735, 1968, 5);
  23. INSERT INTO games_rate VALUES (744, 457, 5);
  24. INSERT INTO games_rate VALUES (746, 457, 5);
  25. INSERT INTO games_rate VALUES (743, 457, 4);
  26. INSERT INTO games_rate VALUES (747, 2, 4);
  27. INSERT INTO games_rate VALUES (745, 547, 4);


Chyba najlepszym rozwiązaniem będze dodanie pola do bazy zawierającego średnią ocenę
thek
Po pierwsze: Patrzę na tabelę z ocenami i widzę jedną głupotę. Jak użytkownik może kilka razy ocenić tę samą grę? Nie widzisz tego?
1 test 5
1 test 3

2 test 2
3 test 5
3 test 1

Gry numer 1 i 3 zostały ocenione przez tego samego usera dwukrotnie. Tego należy uniknąć. Jeśli już się tego pozbędziesz to napisanie zapytania robiącego coś w stylu
  1. SELECT game_id, avg(rate) AS srednia FROM games_rate GROUP BY game_id ORDER BY srednia DESC
a co zrobiłeś wcześniej xamrex da faktycznie prawidłowy rezultat. Na ten moment też powinno. O ile tabela nie ma byków!
xamrex
Cytat
Gry numer 1 i 3 zostały ocenione przez tego samego usera dwukrotnie. Tego należy uniknąć. Jeśli już się tego pozbędziesz to napisanie zapytania robiącego coś w stylu

W bazie tak nie mam, Podałem zły przykład.
Łał zapytanie pięknie działa

Domyślam się, że zapytanie wyświetla jeśli gra była oceniona min 2 razy czy to prawda?
thek
Nie... Grupowanie działa już przy choć jednym rekordzie. Wystarczy więc minimum jedna ocena i zapytanie liczące średnią tej gry ruszy. Średnia z jednej oceny równa się jej samej, matematycznie patrząc.
xamrex
dzięki za odpowiedz
Czy da się zmodyfikować zapytanie żeby wyświetlał game_id i srednia (Lecz musi być min 2 głosów)?
thek
Tak... musisz minimalną liczbę głosow określić w klauzuli HAVING tuż za warunkiem dla GROUP BY, czyli przykładowo GROUP BY game_id HAVING count(rate) > 1
xamrex
bardzo dziękuję za pomoc.
thek
SQL i pisanie w nim zapytań jest proste jeśli ktoś zna podstawy tego języka (kolejność i składnię klauzul) i umie angielski. Zapytanie można bowiem do nich wtedy ładnie zapisać. Przykładem jest Twoje choćby:
SELECT game_id, avg(rate) AS srednia FROM games_rate GROUP BY game_id HAVING count(rate) > 1 ORDER BY srednia DESC
Wybierz ( SELECT ) game_id i średnią ( avg ) głosów nazywając ją ( AS ) srednia z ( FROM ) games_rate grupując głosy po ( GROUP BY ) game_id i jeśli dla danego game_id posiadającego (HAVING) więcej niż jedną ocenę (count(rate) > 1 ) zaś całość wyników uporządkuj ( ORDER BY ) po średniej - malejąco ( DESC ) smile.gif Jak widzisz, jest to dość proste i naturalne, jeśli dobrze sie całość opisze. Czasem jest trudniej jeśli ktoś pomyli kolejność, użyje słów zarezerwowanych bądź zrobi byka, literówkę. Wtedy się potrafi parser burzyć.
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.