Tworze stronę na której ma być wyświetlony ranking graczy. Obecnie mam dwie tabele z graczami i drugą z informacjami o meczach miedzy nimi. Tabele poniżej.
Tabela gracze:
Tabela fow_data z meczami:
Jak teraz stworzyć ranking graczy. Moje zapytanie jakie zrobiłem to:
SELECT SUM(punkty1) AS punkty1, gospodarz
FROM fow_data
GROUP BY gospodarz ORDER BY punkty1 DESC
Ale to zapytanie tworzy ranking dla kolumny gospodarz nie uwzględniając gracza krzys, który był przeciwnikiem bartka i ajaxa a także zdobył punkty (punkty2).
Jest możliwe w ogóle zrobienie takiego rankingu aby uwzględniał punkty i graczy z dwóch kolumn. Np gracz ajax powinien mieć 71 punkty.
Chętnie zobaczę rozwiązanie na joinie, owszem da się to zrobić w samej bazie, ale tylko za pomocą stworzenia funkcji. Nie wspomniałem o tym celowo ponieważ będzie to rozwiązanie dużo trudniejsze we wdrożeniu dla autora ponieważ ledwo radzi sobie z podstawami.
W SQL trzeba by zaprojektować całą bazę danych, zastanowić się jakie dane są nam potrzebne i jakie będą gromadzone, następnie przeprowadzić proces normalizacji lub zaprojektować bazę danych od góry (projektowanie zstępujące) i wypisać wszystkie encje w bazie danych ich pola oraz wykreślić relacje jakie pomiędzy nimi zachodzą.
W PHP musiałbyś mieć algorytm mniej więcej taki:
Utwórz zmienną suma punktów z wartością początkową 0
Pobierz z tabeli gdzie gospodarz lub przeciwnik nazywa się XXX
Dla każdego pobranego rekordu w pętli:
a) jeśli gospodarz to XXX dodaj punkty1 do sumy punktów
b) w przeciwnym wypadku jeśli przeciwnik to XXX dodaj punkty2 do sumy punktów
Wyłuskanie sumy punktów osoby występującej w obu kolumnach (gospodarz i przeciwnik) tabeli fow_data uzyskamy tak:
SELECT g.gospodarz, p1.punkty1 + p2.punkty2
FROM `fow_data` AS g
INNER JOIN `fow_data` AS p1 ON p1.gospodarz = g.gospodarz
INNER JOIN `fow_data` AS p2 ON p2.przeciwnik = g.gospodarz
Jeszcze pozostaje kwestia wypisania osób występujących tylko w jednej z tych 2 kolumn i połączenia tego w całość - być moze da się to jakoś zrobić, ale moja wiedza o MySQL nie jest zbyt duża.
[…] Dodatkowo dochodzi to, że nie dostajemy wyniku jaki oczekiwaliśmy oraz co jeśli jeden gracz grał w N meczach, w przykładzie mieliśmy maksymalnie 2 mecze, ale równie dobrze może być ich 100. Jeśli jakimś cudem Twoje zapytanie przeszłoby przez interpreter to mielibyśmy pokraczną listę z sumą punktów z pierwszego meczu jaki gracz odbył jako gospodarz oraz pierwszego meczu w którym był przeciwnikiem.
Kolejna kwestia jest taka że złączenia zawsze są kosztowne, a Ty proponujesz zrobić dwa do tej samej tabeli do tego złączenie nie odbywa się po indeksach tabeli czyli jest jeszcze bardziej kosztowne i czasochłonne. Efekt tego będzie taki że będziemy przetwarzać więcej danych w tymczasowej tabeli utworzonej ze złączenia pierwszego (a co tu mówić o drugim) niż jest w samej tabeli.
Można by to robić selectem i funkcją sum pod warunkiem że mielibyśmy dobrze zaprojektowaną bazę danych. Przy tej tabeli w grę wchodzi albo funkcja w MySQL albo oprogramowanie tego w PHP.
Generalnie nie wiem po co ci w takim modelu pierwsza tabela.
Jak rozumiem ranking to suma punkt1 i punkty2 w zależności od tego czy gracz jest analogicznie gospodarzem czy przeciwnikiem, więc dla ajax wychodzi na moje oko 61 , a nie 71.
Chcę, żebyś zrozumiał, że to co ci teraz podam rozwiąże twój tymczasowy problem, ale nie rozwiąże twoich głębszych problemów. Np. jeśli kiedyś będzie 2000 graczy, a ty będziesz chciał zrobić tabelkę TOP 5, która nie zarżnie bazy danych, to tego nie zrobisz. Masz błędy w podstawach projektowania baz danych.
A taki szybki fix na potrzeby wyciągnięcia całości tabeli, musisz dodać id do tabeli i zrobić tak jak ja w tym fidzie: http://sqlfiddle.com/#!9/06b54/6
id jest potrzebne bo przy unii rekordy które są duplikatami zostaną pominięte.
Możesz to zobaczyć wykonując takie zapytanie, które zwróci 5 rekordów (bartek z wiersza 1 nie różni się niczym od tego z wiersza 2):
Oczywiście to co jest tam jest bardzo, bardzo złe i nie powinno się tak robić jeśli coś piszemy na poważnie.
Nie zauważyłem ale źle dodałem obrazek z meczami tam oczywiście jest kolumna id. Jeśli miałbym identyfikatory zamiast nazw prościej byłoby utworzyć odpowiednie zapytanie czy nadal byłoby to problemem ?
Mogę przeprojektować bazę danych aby była poprawna.