Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL][PHP]Potrzebna rada mądrzejszego z MAX GROUP BY, Połączenie 3 tablic + GROUP BY + MAX SELECT
lucasnetwork
post
Post #1





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 17.03.2013

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


Witam Wszystkich,

potrzebuję rady kogoś mądrzejszego, bo od dwóch dni szukam po różnych forach rozwiązania, na blogach, w manualu i w żaden sposób nie mogę sobie poradzić. Mam 3 tablice przechowujące dane:

Tablica account: ac_id, auth
Tablica dle_users: user_id, name, auth_user
Tablica game: game_id, account_id, score, secondsPlayed, started

Chcę utworzyć ranking, który pokaże, który gracz zajmuje kolejno pierwsze, drugie, trzecie itd. miejsce sortując według ilość punktów (score), a w przypadku remisu - czasu gry (secondsPlayed). Kombinuję w różny sposób z podzapytaniami i tworząc pętle, ale nadal nie ma tego, co powinno być.

Poniżej ranking, który ma wyglądać następująco:
Miejsce | Gracz | Wynik | Czas
1 | Aneta | 24 | 2:07
2 | Marcin | 24 | 2:21
3 | Marek | 21 | 1:50

O ile nie ma remisu to problemu nie ma, jeśli jednak jest remis pojawia się problem z błędnym przypisywaniem czasu.

Kod zapytania MYSQL w PHP:
  1. $i=1;
  2. $data1 = '2013-02-17 18:03:28';
  3. $data2 = '2013-03-17 18:03:28';
  4. $account = mysql_query("SELECT a.*, b.*, c.*, MAX(c.score) AS wynik FROM account AS a, dle_users AS b, game AS c
  5. WHERE a.auth=b.auth_user AND a.ac_id=c.account_id AND c.started BETWEEN '$data1' AND '$data2'
  6. GROUP BY c.account_id ORDER BY wynik DESC, c.secondsPlayed ASC LIMIT 5");
  7. while( $ranking = mysql_fetch_assoc( $account ))
  8. {
  9. $seconds = $ranking[secondsPlayed];
  10. $min = floor ($seconds / 60);
  11. $sec = $seconds % 60;
  12. echo '<tr align="center"><td>'.$i++.'</td><td>'.$ranking[name].'</td><td>'.$ranking[wynik].'</td><td>'.$min.':';if (strlen($sec)==1){echo '0';} echo $sec.'</td></tr>';
  13. }


Problem w tym, że prawidłowo jest pobierany najwyższy wynik gracza w określonym przedziale daty, ale pozostałe pola rekordu nie są prawidłowo przypisywane. Czas gry (secondsPlayed), który jest w rekordzie z najwyższym wynikiem (score) już nie jest pobierany z prawidłowego pola tylko pierwszy z całej tablicy, gdzie id gracza (account_id) znajduje się.

Aby to zobrazować poniżej kawałek tablicy game:

game_id | account_id | score | secondsPlayed
1 | 4 | 8 | 101
2 | 5 | 16 | 120
3 | 4 | 24 | 127

Zapytanie pobiera prawodłowo MAX(score) jako 24 grupując po ID gracza (w przykładzie account_id = 4), ale już czas gry (secondsPlayed) zamiast 127 sekund pobiera 101.

W jakimś stopniu znalazłem rozwiązanie w ten sposób:
  1. $i=1;
  2. $data1 = '2013-02-17 18:03:28';
  3. $data2 = '2013-03-17 18:03:28';
  4. $account = mysql_query("SELECT a.*, b.*, c.*, MAX(c.score) AS wynik FROM account AS a, dle_users AS b, game AS c
  5. WHERE a.auth=b.auth_user AND a.ac_id=c.account_id AND c.started BETWEEN '$data1' AND '$data2'
  6. GROUP BY c.account_id ORDER BY wynik DESC LIMIT 5");
  7. while( $ranking = mysql_fetch_assoc( $account ))
  8. {
  9. $result = mysql_query("SELECT account_id, score, secondsPlayed FROM game WHERE score = ".$ranking[wynik]." AND account_id = ".$ranking[account_id]."");
  10. $result = mysql_fetch_assoc($result);
  11. $seconds = $result[secondsPlayed];
  12. $min = floor ($seconds / 60);
  13. $sec = $seconds % 60;
  14. echo '<tr align="center"><td>'.$i++.'</td><td>'.$ranking[name].'</td><td>'.$ranking[wynik].'</td><td>'.$min.':';if (strlen($sec)==1){echo '0';} echo $sec.'</td></tr>';
  15. }

W pętli jest zapytanie, które wyszukuje znalezione wcześniej MAX(score) i porównuje je z ID gracza (account_id). W ten sposób przypisywany jest już właściwy czas secondsPlayed, ale jak to posortować, kiedy w punktach jest remis?
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: 25.08.2025 - 02:38