somme de champs + classements de ces sommes

Petit nouveau ! | 3 Messages

10 août 2006, 16:46

Bonjour à tous.
Voici mon problème, j'ai une table de résultats de matches de cette forme:

Code : Tout sélectionner

| home_team | away_team | home_score | away_score | | A | X | 3 | 1 | | Y | A | 1 | 2 | | X | Y | 2 | 1 |
J'aimerai récupérer le nombre de but marqué pour chaque équipe et le classer par ordre croissant sous mySQL.
Mon souci vient du fait que le score n'est jamais dans la même colonne.
Ma requête ne prend pas en compte cette différence. En 2 requêtes sur chaque colonne, ça donne la somme, mais ça ne me les classe pas.

Est ce possible de le faire ? Et pourriez vous me mettre sur la voie...

Je pourrai aussi me simplifier la vie en créant une autre table mais je trouve ça moins flexible.
Merci
Modifié en dernier par shockiii le 10 août 2006, 19:30, modifié 1 fois.

Eléphanteau du PHP | 27 Messages

10 août 2006, 16:58

C'est clair que c'est pas la meilleur façon d'enregistrer les données. Surtout pour faire ensuite des stats !

Sinon voici les manips (fastidieuses) à faire :

Lister d'abord dans un tableau les équipes ayant joué à domicile en les triant et totalisant leurs scores (avec une requête sql):

A 3
X 2
Y 1

Faire la même chose dans un autre tableau pour les équipe ayant joué chez les autres (avec le même genre de requete sql) :

A 2
X 1
Y 1

Puis fusionner les deux tableaux dans PHP pour avoir :

A 5
X 3
Y 2

Mais je te conseille d'organiser autrement ta table genre

Match | Equipe | Lieu | Score
1 | A | 1 | 1
1 | X | 0 | 2
2 | X | 1 | 0
2 | Y | 0 | 3

Tu défini par exemple que le lieu 1 c'est à domicile et 0 chez les autres.
Tes stats seront mille fois plus faciles à faire.

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

10 août 2006, 17:16

Avec ta table actuelle tu peux aussi faire ça en une seule requête avec une auto-jointure

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

10 août 2006, 17:20

Mais effectivement tu pourrais peut-être étudier une autre organisation.

Déjà rien que le fait de stocker à chaque le nom des équipes n'est pas terrible, tu stockes plusieurs fois des chaines ce qui alourdit la table, et si une équipe change de nom il faut que tu la changes partout.

Une table Equipes, une table Matchs, serait pas mal ;)

Petit nouveau ! | 3 Messages

10 août 2006, 17:32

J'y avais pensé faber8 mais pas pratique du tout.
Quand on a 380 matches au total, il faut importer dans la base et c'est fastidieux qui plus est multiplié une 12aine de fois. Les calendriers que j'ai sont quasi prêts à être importés. C'est pour ça que je ne veux pas trop toucher à l'organisation.

Le plus simple est d'utiliser une autre table mais je voulais faire ce genre de requete pour pouvoir donner des limites (entre la X et Y ème journée).

Sinon ouckileou, j'ai déjà une table pour les équipes, là c'est juste un exemple. J'utilise les id des équipes dans cette table.

Je crois que je vais me tourner vers ma table classement avec des entrées pour chaque journée.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

10 août 2006, 17:43

Avant toute chose, quel SGBD et quelle version utilises-tu ?

On pourrait utiliser une table dérivée basée sur une UNION pour récupérer tous les résultats et les classer par équipe, en l'occurence:

Code : Tout sélectionner

SELECT SUM(score) AS total, team FROM ( SELECT home_team AS team, SUM(home_score) AS score FROM matches GROUP BY home_team UNION ALL SELECT away_team AS team, SUM(away_score) AS score FROM matches GROUP BY away_team ) AS tmp GROUP BY team ORDER BY total DESC
ou encore

Code : Tout sélectionner

SELECT SUM(score) AS total, team FROM ( SELECT home_team AS team, home_score AS score FROM matches UNION ALL SELECT away_team AS team, away_score AS score FROM matches ) AS tmp GROUP BY team ORDER BY total DESC
et peut-être même

Code : Tout sélectionner

SELECT COALESCE(t1.score, 0) + COALESCE(t2.score, 0) AS total, COALESCE(t1.team, t2.team) AS team FROM ( SELECT home_team AS team, SUM(home_score) AS score FROM matches GROUP BY home_team ) AS t1 FULL JOIN ( SELECT away_team AS team, SUM(away_score) AS score FROM matches GROUP BY away_team ) AS t2 USING (team) ORDER BY total DESC
À voir lequel est le plus rapide.

Petit nouveau ! | 3 Messages

10 août 2006, 19:29

Ah oui, désolé, je n'avais pas précisé, mySQL.

Sinon, merci beaucoup, les 3 requêtes fonctionnent (la 3ème, remplacer FULL JOIN par JOIN tout court). C'est exactement ce que je cherchais à faire mais je ne savais pas comment. Ca m'eclaircie pas mal, merci, et ça me permet de comprendre un peu mieux.
Sinon, niveaux temps en essayant sous phpmyadmin, les temps se valent.
Requête 1: 0.0023 sec
Requête 2: 0.0024 sec
Requête 3: 0.0022 sec

Donc je vais opter pour la plus clair à mes yeux.
Merci encore.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

10 août 2006, 19:37

Attention, si tu n'utilises pas de FULL JOIN avec la 3eme elle ne fonctionnera que si chaque équipe a joué au moins une fois à domicile et à l'extérieur.

Pour tester les performances des requêtes n'oublie pas de prendre en compte l'augmentation du nombre de matches. Si tu veux des explis sur le fonctionnement des requêtes n'hésite pas ;)