Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL][PHP]Sortowanie wedłu średniej ocen
xamrex
post
Post #1





Grupa: Zarejestrowani
Postów: 267
Pomógł: 1
Dołączył: 10.08.2007

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


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ć

Ten post edytował xamrex 6.06.2010, 22:53:53
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 11)
Wicepsik
post
Post #2





Grupa: Zarejestrowani
Postów: 1 575
Pomógł: 299
Dołączył: 26.03.2009

Ostrzeżenie: (20%)
X----


http://dev.mysql.com/doc/refman/5.0/en/gro...ml#function_avg
Go to the top of the page
+Quote Post
xamrex
post
Post #3





Grupa: Zarejestrowani
Postów: 267
Pomógł: 1
Dołączył: 10.08.2007

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


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

Ten post edytował xamrex 6.06.2010, 22:54:28
Go to the top of the page
+Quote Post
Wicepsik
post
Post #4





Grupa: Zarejestrowani
Postów: 1 575
Pomógł: 299
Dołączył: 26.03.2009

Ostrzeżenie: (20%)
X----


A masz kolumnę rate w tabeli ? Człowieku myśl (IMG:style_emoticons/default/withstupidsmiley.gif)
Go to the top of the page
+Quote Post
xamrex
post
Post #5





Grupa: Zarejestrowani
Postów: 267
Pomógł: 1
Dołączył: 10.08.2007

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


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ę

Ten post edytował xamrex 7.06.2010, 08:13:43
Go to the top of the page
+Quote Post
thek
post
Post #6





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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!
Go to the top of the page
+Quote Post
xamrex
post
Post #7





Grupa: Zarejestrowani
Postów: 267
Pomógł: 1
Dołączył: 10.08.2007

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


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?

Ten post edytował xamrex 7.06.2010, 13:56:02
Go to the top of the page
+Quote Post
thek
post
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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.
Go to the top of the page
+Quote Post
xamrex
post
Post #9





Grupa: Zarejestrowani
Postów: 267
Pomógł: 1
Dołączył: 10.08.2007

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


dzięki za odpowiedz
Czy da się zmodyfikować zapytanie żeby wyświetlał game_id i srednia (Lecz musi być min 2 głosów)?

Ten post edytował xamrex 7.06.2010, 16:17:45
Go to the top of the page
+Quote Post
thek
post
Post #10





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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
Go to the top of the page
+Quote Post
xamrex
post
Post #11





Grupa: Zarejestrowani
Postów: 267
Pomógł: 1
Dołączył: 10.08.2007

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


bardzo dziękuję za pomoc.
Go to the top of the page
+Quote Post
thek
post
Post #12





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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 ) (IMG:style_emoticons/default/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ć.
Go to the top of the page
+Quote Post

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: 24.12.2025 - 23:01