Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Difficulté sur une requête SQL

5 réponses
Avatar
jibux
Bonjour,

Soit une première requête qui donne pour chaque joueur toutes leurs années
d'inscription

SELECT jo_nom, jo_prénom, as_nom
FROM
joueur
INNER JOIN classement_ELO ON joueur.jo_ID = classement_elo.jo_ID
INNER JOIN année_scolaire ON classement_ELO.as_id = année_scolaire.as_id

order by jo_nom,jo_prénom,as_nom;


Et celle-ci qui donne pour chaque joueur le nombre de matchs effectués
chaque année

SELECT jo_nom, jo_prénom, as_nom, count(ré_classement)
FROM
joueur
inner JOIN résultat ON joueur.jo_ID = résultat.jo_ID
inner JOIN évènement ON résultat.év_id = évènement.év_ID
inner JOIN année_scolaire ON évènement.as_ID = année_scolaire.as_id

group by jo_nom, jo_prénom, as_nom


Je souhaite en fait obtenir quelque chose comme :
SELECT jo_nom, jo_prénom, as_nom, nb_match
...

avec 1 ligne par joueur et par année sachant qu'un joueur peu très bien
n'effectuer aucun match une année.

Toutes mes tentatives ayant echouées (union, left join en tout genre ...) je
m'en remet à votre expertise

D'avance merci.


Voici la définition des tables :

CREATE TABLE `année_scolaire` (
`as_ID` int(10) unsigned NOT NULL auto_increment,
`as_nom` varchar(9) NOT NULL default '',
`as_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`as_ID`)
) TYPE=MyISAM COMMENT='Ensemble des années scolaires' AUTO_INCREMENT=8 ;

CREATE TABLE `classement_ELO` (
`cE_ID` int(10) unsigned NOT NULL auto_increment,
`jo_ID` int(10) unsigned NOT NULL default '0',
`as_ID` int(10) unsigned NOT NULL default '0',
`cE_long` int(10) unsigned NOT NULL default '0',
`cE_rapide` int(11) unsigned NOT NULL default '0',
`cE_equipe_ac` enum('oui','non','1er Ech.','2ème Ech.','3ème Ech.','4ème
Ech.','5ème Ech.','6ème Ech.','7ème Ech.','8ème Ech.') NOT NULL default
'non',
`cE_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`cE_ID`)
) TYPE=MyISAM COMMENT='Ensembles des classements ELO de tous les joueurs'

CREATE TABLE `joueur` (
`jo_ID` int(11) NOT NULL auto_increment,
`jo_nom` varchar(255) NOT NULL default '',
`jo_prénom` varchar(255) NOT NULL default '',
`jo_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`jo_ID`)
) TYPE=MyISAM COMMENT='Ensemble de tous les joueurs' AUTO_INCREMENT=76 ;

CREATE TABLE `résultat` (
`ré_ID` int(10) unsigned NOT NULL auto_increment,
`jo_ID` int(10) unsigned NOT NULL default '0',
`év_ID` int(10) unsigned NOT NULL default '0',
`ré_points` decimal(3,1) unsigned NOT NULL default '0.0',
`ré_classement` int(10) unsigned NOT NULL default '0',
`ré_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`ré_ID`)
) TYPE=MyISAM AUTO_INCREMENT=302 ;

CREATE TABLE `évènement` (
`év_ID` int(10) unsigned NOT NULL auto_increment,
`té_ID` int(10) unsigned NOT NULL default '0',
`as_ID` int(10) unsigned NOT NULL default '0',
`év_date` date NOT NULL default '0000-00-00',
`év_lieu` varchar(255) NOT NULL default '',
`év_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`év_ID`)
) TYPE=MyISAM AUTO_INCREMENT=31 ;

--
jeb
http://jebissey.free.fr

5 réponses

Avatar
Antoun
Le schéma de ta base est donc qqch comme ça :


JOUEUR --- CLASSEMENT --- ANNEE SCOL --- EVENEMENT
| |
------------------------------------> RESULTAT

Or, je suppose que si un joueur n'a participé à aucun match, il n'a pas
de classement ELO ? du coup, cela t'empêche de passer de Jouer à Année
scolaire.

Il faut donc que tu commences par générer tous les couples (Joueur,
Année scolaire) possibles avec un produit cartésien ; à partir de là, tu
fais des LEFT JOIN sur Evénement et Résultat.

ça devrait donc ressembler à qqch comme ça :

Select jo_nom, jo_prénom, as_nom, count(*) as nb_matchs
From joueur J
CROSS JOIN année_scolaire A
LEFT JOIN évènement E ON A.as_id = E.év_ID
LEFT JOIN résultat R ON J.jo_id = R.jo_id AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom,
order by jo_nom,jo_prénom,as_nom

qq petites remarques :

- dans ton CREATE TABLE événement, tu crées un té_ID au lieu d'un ré_id

- c'est bien de donner tes CREATE TABLE... avec qq lignes de données
sous forme de INSERT, c'est encore mieux !

- attention, dans ta première requête tu écris classement_elo.jo_ID au
lieu de classement_ELO.jo_ID ; ça passe sans pb en local sur ton
Windows, mais quand tu mettras ça sur le serveur Linux de Free tu auras
des surprises... au passage, tu noteras que je simplifie l'écriture des
jointures en donnant des alias aux tables (J pour joueur, A pour
année_scolaire, etc.)

- selon l'ampleur temporelle de tes données, générer tous les couples
(Joueur, Année scolaire) peut t'amener à présenter des données idiotes,
comme "Machin, 1960-61 : 0 matchs", "Machin, 1961-62 : 0 matchs", etc.
pour un gars né en 1980. Dans ce cas, tu peux par exemple vouloir te
limiter aux années comprises entre la première et la dernière
participation. En supposant que le tri de tes as_id soit
chronologiquement valable, tu peux générer une table temporaire de ce
genre là :

CREATE TEMPORARY TABLE joueur_periode
SELECT jo_id, min(as_id) AS as_id_deb, max(as_id) AS as_id_fin
FROM joueur J
INNER JOIN classement_ELO C ON J.jo_id = C.jo_id
;

ensuite tu remplaces le

joueur J
CROSS JOIN année_scolaire A

par qqch comme

joueur J
INNER JOIN joueur_periode JP ON J.jo_id = JP.jo_id
INNER JOIN année_scolaire A
ON A.as_id BETWEEN JP.as_id_deb AND JP.as_id_fin
Avatar
Antoun
[SECOND ENVOI, SUITE A CORRECTION COQUILLE]

Le schéma de ta base est donc qqch comme ça :


JOUEUR --- CLASSEMENT --- ANNEE SCOL --- EVENEMENT
| |
------------------------------------- RESULTAT

Or, je suppose que si un joueur n'a participé à aucun match, il n'a pas
de classement ELO ? du coup, cela t'empêche de passer de Jouer à Année
scolaire.

Il faut donc que tu commences par générer tous les couples (Joueur,
Année scolaire) possibles avec un produit cartésien ; à partir de là, tu
fais des LEFT JOIN sur Evénement et Résultat.

ça devrait donc ressembler à qqch comme ça :

Select jo_nom, jo_prénom, as_nom, count(*) as nb_matchs
From joueur J
CROSS JOIN année_scolaire A
LEFT JOIN évènement E ON A.as_id = E.év_ID
LEFT JOIN résultat R ON J.jo_id = R.jo_id AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom,
order by jo_nom,jo_prénom,as_nom

qq petites remarques :

- dans ton CREATE TABLE événement, tu crées un té_ID au lieu d'un ré_id

- c'est bien de donner tes CREATE TABLE... avec qq lignes de données
sous forme de INSERT, c'est encore mieux !

- attention, dans ta première requête tu écris classement_elo.jo_ID au
lieu de classement_ELO.jo_ID ; ça passe sans pb en local sur ton
Windows, mais quand tu mettras ça sur le serveur Linux de Free tu auras
des surprises... au passage, tu noteras que je simplifie l'écriture des
jointures en donnant des alias aux tables (J pour joueur, A pour
année_scolaire, etc.)

- selon l'ampleur temporelle de tes données, générer tous les couples
(Joueur, Année scolaire) peut t'amener à présenter des données idiotes,
comme "Machin, 1960-61 : 0 matchs", "Machin, 1961-62 : 0 matchs", etc.
pour un gars né en 1980. Dans ce cas, tu peux par exemple vouloir te
limiter aux années comprises entre la première et la dernière
participation. En supposant que le tri de tes as_id soit
chronologiquement valable, tu peux générer une table temporaire de ce
genre là :

CREATE TEMPORARY TABLE joueur_periode
SELECT jo_id, min(as_id) AS as_id_deb, max(as_id) AS as_id_fin
FROM joueur J
INNER JOIN classement_ELO C ON J.jo_id = C.jo_id
;

ensuite, dans la requête principale, tu remplaces le

joueur J
CROSS JOIN année_scolaire A

par qqch comme

joueur J
INNER JOIN joueur_periode JP ON J.jo_id = JP.jo_id
INNER JOIN année_scolaire A
ON A.as_id BETWEEN JP.as_id_deb AND JP.as_id_fin
Avatar
jibux
Antoun wrote:

Merci pour cette réponse très précise.

Le schéma de ta base est donc qqch comme ça :
JOUEUR --- CLASSEMENT --- ANNEE SCOL --- EVENEMENT
| |
------------------------------------- RESULTAT


Exactement

Or, je suppose que si un joueur n'a participé à aucun match, il n'a pas
de classement ELO ? du coup, cela t'empêche de passer de Jouer à Année
scolaire.


Non, tous les joueurs on un classement ELO, on leur attribue même la
première fois qu'il joue une classement 'fictif' qui dépend de l'age.

Il faut donc que tu commences par générer tous les couples (Joueur,
Année scolaire) possibles avec un produit cartésien ; à partir de là, tu
fais des LEFT JOIN sur Evénement et Résultat.

ça devrait donc ressembler à qqch comme ça :

Select jo_nom, jo_prénom, as_nom, count(*) as nb_matchs
From joueur J
CROSS JOIN année_scolaire A
LEFT JOIN évènement E ON A.as_id = E.év_ID
LEFT JOIN résultat R ON J.jo_id = R.jo_id AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom,
order by jo_nom,jo_prénom,as_nom



En adaptant ta requête pour mySQL qui ne connaît pas CROSS JOIN j'arrive à :

SELECT jo_nom, jo_prénom, as_nom, count( * ) AS nb_matchs
FROM joueur AS J, année_scolaire AS A
LEFT JOIN évènement AS E ON A.as_id = E.év_ID
LEFT JOIN résultat AS R ON J.jo_id = R.jo_id
AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom
ORDER BY jo_nom, jo_prénom, as_nom

Je n'obtiens pas le résultat attendu pour le jeu d'essai (cf plus bas)
soit :
jo_nom jo_prénom as_nom nb_matchs
A Benoît 1998-1999 0
B Vivien 2004-2005 2
C Pierre 2004-2005 2
D Florent 2002-2003 0
D Florent 2003-2004 6
D Florent 2004-2005 10
E Hélène 2004-2005 2
F Cyril 2003-2004 10
F Cyril 2004-2005 12
G Lucie 2004-2005 14


Ma transformation ne respecte peut-être pas ta requête initiale. En tout cas
j'espère que je jeu d'essai (si tu veux encore un peu réfléchir sur mon
problème) te permettra de trouver la solution.

qq petites remarques :

- dans ton CREATE TABLE événement, tu crées un té_ID au lieu d'un ré_id


Oui je crée un té_id en plus du ré_id (identifiant de la table résultat) qui
est une clé étrangère sur la table type_évènement. Celle-ci n'est pas
utilisé dans cette requête.


- c'est bien de donner tes CREATE TABLE... avec qq lignes de données
sous forme de INSERT, c'est encore mieux !


Voilà, pour tester c'est effectivement plus facile.

CREATE TABLE `année_scolaire` (
`as_ID` int(10) unsigned NOT NULL auto_increment,
`as_nom` varchar(9) NOT NULL default '',
`as_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`as_ID`)
) TYPE=MyISAM COMMENT='Ensemble des années scolaires' AUTO_INCREMENT=8 ;

INSERT INTO `année_scolaire` VALUES (1, '2004-2005', '20050223223317');
INSERT INTO `année_scolaire` VALUES (2, '2003-2004', '20050223223332');
INSERT INTO `année_scolaire` VALUES (3, '2002-2003', '20050223223345');
INSERT INTO `année_scolaire` VALUES (4, '1998-1999', '20050513191749');
INSERT INTO `année_scolaire` VALUES (5, '1999-2000', '20050702133547');
INSERT INTO `année_scolaire` VALUES (6, '2000-2001', '20050702133547');
INSERT INTO `année_scolaire` VALUES (7, '2001-2002', '20050702135504');

CREATE TABLE `classement_ELO` (
`cE_ID` int(10) unsigned NOT NULL auto_increment,
`jo_ID` int(10) unsigned NOT NULL default '0',
`as_ID` int(10) unsigned NOT NULL default '0',
`cE_long` int(10) unsigned NOT NULL default '0',
`cE_rapide` int(11) unsigned NOT NULL default '0',
`cE_equipe_ac` enum('oui','non','1er Ech.','2ème Ech.','3ème Ech.','4ème
Ech.','5ème Ech.','6ème Ech.','7ème Ech.','8ème Ech.') NOT NULL default
'non',
`cE_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`cE_ID`)
) TYPE=MyISAM COMMENT='Ensembles des classements ELO de tous les joueurs
pour toute' AUTO_INCREMENT0 ;

INSERT INTO `classement_ELO` VALUES (1, 1, 1, 1250, 1400, '3ème Ech.',
'20050523093210');
INSERT INTO `classement_ELO` VALUES (2, 2, 1, 1099, 1330, '8ème Ech.',
'20050514093930');
INSERT INTO `classement_ELO` VALUES (3, 3, 1, 1199, 1130, '5ème Ech.',
'20050514093947');
INSERT INTO `classement_ELO` VALUES (26, 3, 2, 1199, 970, 'non',
'20050319134336');
INSERT INTO `classement_ELO` VALUES (27, 1, 2, 1099, 1099, '8ème Ech.',
'20050514094119');
INSERT INTO `classement_ELO` VALUES (52, 30, 1, 0, 0, 'non',
'20050219195423');
INSERT INTO `classement_ELO` VALUES (53, 31, 1, 0, 0, 'non',
'20050219195428');
INSERT INTO `classement_ELO` VALUES (58, 36, 1, 0, 0, 'non',
'20050219195959');
INSERT INTO `classement_ELO` VALUES (78, 56, 4, 1199, 1199, 'non',
'20050513200732');
INSERT INTO `classement_ELO` VALUES (80, 3, 3, 0, 0, 'non',
'20050702103327');


CREATE TABLE `joueur` (
`jo_ID` int(11) NOT NULL auto_increment,
`jo_nom` varchar(255) NOT NULL default '',
`jo_prénom` varchar(255) NOT NULL default '',
`jo_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`jo_ID`)
) TYPE=MyISAM COMMENT='Ensemble de tous les joueurs' AUTO_INCREMENTv ;

INSERT INTO `joueur` VALUES (1, 'F', 'Cyril', '20050703094555');
INSERT INTO `joueur` VALUES (2, 'G', 'Lucie', '20050703094608');
INSERT INTO `joueur` VALUES (3, 'D', 'Florent', '20050703094520');
INSERT INTO `joueur` VALUES (30, 'B', 'Vivien', '20050703094454');
INSERT INTO `joueur` VALUES (31, 'C', 'Pierre', '20050703094506');
INSERT INTO `joueur` VALUES (36, 'E', 'Hélène', '20050703094542');
INSERT INTO `joueur` VALUES (56, 'A', 'Benoît', '20050703094438');


CREATE TABLE `résultat` (
`ré_ID` int(10) unsigned NOT NULL auto_increment,
`jo_ID` int(10) unsigned NOT NULL default '0',
`év_ID` int(10) unsigned NOT NULL default '0',
`ré_points` decimal(3,1) unsigned NOT NULL default '0.0',
`ré_classement` int(10) unsigned NOT NULL default '0',
`ré_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`ré_ID`)
) TYPE=MyISAM AUTO_INCREMENT02 ;

INSERT INTO `résultat` VALUES (1, 2, 2, 5.0, 6, '20050213184601');
INSERT INTO `résultat` VALUES (2, 3, 2, 4.0, 13, '20050213185416');
INSERT INTO `résultat` VALUES (14, 2, 3, 4.5, 7, '20050214154921');
INSERT INTO `résultat` VALUES (16, 1, 3, 4.0, 8, '20050214160103');
INSERT INTO `résultat` VALUES (20, 3, 3, 3.0, 16, '20050214160441');
INSERT INTO `résultat` VALUES (25, 1, 4, 5.5, 4, '20050214160724');
INSERT INTO `résultat` VALUES (26, 2, 4, 5.0, 7, '20050214160743');
INSERT INTO `résultat` VALUES (30, 3, 4, 3.0, 22, '20050214160929');
INSERT INTO `résultat` VALUES (37, 1, 1, 5.5, 4, '20050214161402');
INSERT INTO `résultat` VALUES (48, 2, 1, 4.0, 15, '20050214161521');
INSERT INTO `résultat` VALUES (49, 3, 10, 3.0, 18, '20050216153823');
INSERT INTO `résultat` VALUES (50, 1, 10, 4.0, 15, '20050216153843');
INSERT INTO `résultat` VALUES (59, 2, 5, 5.0, 3, '20050219180017');
INSERT INTO `résultat` VALUES (60, 1, 5, 4.0, 8, '20050219180100');
INSERT INTO `résultat` VALUES (64, 2, 12, 4.0, 7, '20050219183952');
INSERT INTO `résultat` VALUES (66, 1, 11, 3.0, 1, '20050224205644');
INSERT INTO `résultat` VALUES (67, 2, 11, 3.0, 1, '20050224205653');
INSERT INTO `résultat` VALUES (68, 3, 11, 2.0, 1, '20050224205627');
INSERT INTO `résultat` VALUES (74, 1, 13, 0.0, 1, '20050224221804');
INSERT INTO `résultat` VALUES (82, 1, 14, 0.0, 16, '20050227131853');
INSERT INTO `résultat` VALUES (91, 1, 16, 4.0, 9, '20050319134101');
INSERT INTO `résultat` VALUES (93, 3, 16, 3.0, 22, '20050319134919');
INSERT INTO `résultat` VALUES (99, 1, 17, 5.0, 4, '20050319141030');
INSERT INTO `résultat` VALUES (103, 3, 17, 3.5, 15, '20050319141231');
INSERT INTO `résultat` VALUES (110, 3, 18, 4.0, 9, '20050319151408');
INSERT INTO `résultat` VALUES (111, 1, 18, 4.0, 10, '20050319151425');
INSERT INTO `résultat` VALUES (123, 1, 19, 4.0, 12, '20050319164653');
INSERT INTO `résultat` VALUES (132, 3, 20, 3.0, 15, '20050319170825');
INSERT INTO `résultat` VALUES (136, 1, 21, 4.5, 8, '20050319171754');
INSERT INTO `résultat` VALUES (147, 1, 22, 3.0, 19, '20050319172947');
INSERT INTO `résultat` VALUES (150, 3, 22, 2.5, 24, '20050319173051');
INSERT INTO `résultat` VALUES (152, 1, 23, 2.5, 24, '20050319175431');
INSERT INTO `résultat` VALUES (160, 3, 15, 0.5, 1, '20050323210920');
INSERT INTO `résultat` VALUES (161, 1, 15, 2.5, 1, '20050323210714');
INSERT INTO `résultat` VALUES (162, 2, 15, 4.0, 1, '20050323210705');
INSERT INTO `résultat` VALUES (169, 2, 7, 4.5, 6, '20050430191819');
INSERT INTO `résultat` VALUES (170, 1, 7, 4.0, 12, '20050430191840');
INSERT INTO `résultat` VALUES (174, 3, 7, 3.0, 20, '20050430191948');
INSERT INTO `résultat` VALUES (195, 3, 8, 3.0, 18, '20050514193619');
INSERT INTO `résultat` VALUES (196, 1, 8, 5.0, 3, '20050514193444');
INSERT INTO `résultat` VALUES (197, 2, 8, 4.5, 8, '20050514193504');
INSERT INTO `résultat` VALUES (206, 1, 24, 2.5, 9, '20050525210103');
INSERT INTO `résultat` VALUES (212, 2, 24, 5.0, 9, '20050525210108');
INSERT INTO `résultat` VALUES (213, 3, 24, 2.5, 9, '20050525210052');
INSERT INTO `résultat` VALUES (214, 2, 9, 4.5, 5, '20050606231618');
INSERT INTO `résultat` VALUES (215, 1, 9, 4.0, 13, '20050606231657');
INSERT INTO `résultat` VALUES (225, 1, 28, 17.0, 1, '20050613212646');
INSERT INTO `résultat` VALUES (226, 2, 28, 16.0, 2, '20050613212707');
INSERT INTO `résultat` VALUES (230, 3, 28, 11.0, 6, '20050613212746');
INSERT INTO `résultat` VALUES (249, 30, 29, 11.5, 7, '20050613212940');
INSERT INTO `résultat` VALUES (256, 31, 29, 6.0, 14, '20050613213033');
INSERT INTO `résultat` VALUES (257, 36, 29, 5.5, 15, '20050613213038');
INSERT INTO `résultat` VALUES (262, 30, 30, 0.0, 13, '20050612194708');
INSERT INTO `résultat` VALUES (263, 31, 30, 0.0, 27, '20050612194946');
INSERT INTO `résultat` VALUES (264, 3, 30, 0.0, 12, '20050612194659');
INSERT INTO `résultat` VALUES (265, 36, 30, 0.0, 28, '20050612194950');
INSERT INTO `résultat` VALUES (266, 1, 30, 0.0, 2, '20050612194516');
INSERT INTO `résultat` VALUES (267, 2, 30, 0.0, 3, '20050612194520');


CREATE TABLE `évènement` (
`év_ID` int(10) unsigned NOT NULL auto_increment,
`té_ID` int(10) unsigned NOT NULL default '0',
`as_ID` int(10) unsigned NOT NULL default '0',
`év_date` date NOT NULL default '0000-00-00',
`év_lieu` varchar(255) NOT NULL default '',
`év_timestamp` timestamp(14) NOT NULL,
PRIMARY KEY (`év_ID`)
) TYPE=MyISAM AUTO_INCREMENT1 ;

INSERT INTO `évènement` VALUES (1, 1, 1, '2004-10-09', 'Centre social St
Jacques de Beaune', '20050213180515');
INSERT INTO `évènement` VALUES (2, 1, 1, '2004-11-13', 'Ecole du Breuil de
Chevigny St Sauveur', '20050213175829');
INSERT INTO `évènement` VALUES (3, 1, 1, '2004-12-04', 'Collège Bachelard de
Dijon', '20050213180528');
INSERT INTO `évènement` VALUES (4, 1, 1, '2005-01-22', 'Centre social St
Jacques de Beaune', '20050213180540');
INSERT INTO `évènement` VALUES (5, 1, 1, '2005-02-05', 'Ecole du Breuil de
Chevigny St Sauveur', '20050213180308');
INSERT INTO `évènement` VALUES (6, 1, 1, '2005-03-05', 'Salle des fêtes de
Bonnencontre', '20050213180308');
INSERT INTO `évènement` VALUES (7, 1, 1, '2005-04-30', 'Ecole du Breuil de
Chevigny St Sauveur', '20050404212539');
INSERT INTO `évènement` VALUES (8, 1, 1, '2005-05-14', 'Cercle de Dijon',
'20050213180605');
INSERT INTO `évènement` VALUES (9, 1, 1, '2005-06-04', 'Collège Bachelard de
Dijon', '20050213180623');
INSERT INTO `évènement` VALUES (10, 1, 2, '2004-02-14', 'Cercle de Dijon',
'20050216153644');
INSERT INTO `évènement` VALUES (11, 5, 1, '2005-02-23', 'Ecole Claude
TILLIER à Clamecy', '20050219181240');
INSERT INTO `évènement` VALUES (12, 6, 1, '2005-01-23', 'Centre social St
Jacques de Beaune', '20050219192805');
INSERT INTO `évènement` VALUES (13, 5, 2, '2004-02-18', 'Finale académique à
Autun', '20050227134738');
INSERT INTO `évènement` VALUES (14, 5, 2, '2004-05-23', 'Championnat de
France des Collèges par 8 à CAEN', '20050227131626');
INSERT INTO `évènement` VALUES (15, 5, 1, '2005-03-23', 'Championnat inter
académique au collège Nicolas LEDOUX de Dôle', '20050404212309');
INSERT INTO `évènement` VALUES (16, 1, 2, '2003-11-15', 'Centre social St
Jacques de Beaune', '20050319133841');
INSERT INTO `évènement` VALUES (17, 1, 2, '2003-12-06', 'Ecole du Breuil de
Chevigny St Sauveur', '20050319140628');
INSERT INTO `évènement` VALUES (18, 1, 2, '2003-10-11', 'Ecole du Breuil de
Chevigny St Sauveur', '20050319150634');
INSERT INTO `évènement` VALUES (19, 1, 2, '2004-01-17', 'Collège Bachelard
de Dijon', '20050319163723');
INSERT INTO `évènement` VALUES (20, 1, 2, '2004-03-27', 'Esbarres',
'20050319170229');
INSERT INTO `évènement` VALUES (21, 1, 2, '2004-04-19', 'Cercle de Dijon',
'20050319171202');
INSERT INTO `évènement` VALUES (22, 1, 2, '2004-05-15', 'Cercle de Dijon',
'20050319172404');
INSERT INTO `évènement` VALUES (23, 1, 2, '2004-06-05', 'Collège Bachelard
de Dijon', '20050319174716');
INSERT INTO `évènement` VALUES (24, 5, 1, '2005-05-21', 'Championnat de
France des Collèges par 8 à La Farlède', '20050324211429');
INSERT INTO `évènement` VALUES (25, 5, 4, '1999-03-10', 'Finale académique à
Dijon contre Abel Minard de Tonnerre', '20050513194639');
INSERT INTO `évènement` VALUES (26, 5, 4, '1999-03-30', 'Finale
inter-académique contre Bayard de Charleville- Mezières à Saint-Dizier',
'20050513201357');
INSERT INTO `évènement` VALUES (27, 1, 4, '1999-06-30', 'Classement final
pour l''année 98/99', '20050513204153');
INSERT INTO `évènement` VALUES (28, 4, 1, '2005-05-17', 'Classement poule du
mardi', '20050612192436');
INSERT INTO `évènement` VALUES (29, 4, 1, '2005-05-20', 'Classement poule du
vendredi', '20050612192514');
INSERT INTO `évènement` VALUES (30, 4, 1, '2005-05-27', 'Classement
général', '20050612194245');





- attention, dans ta première requête tu écris classement_elo.jo_ID au
lieu de classement_ELO.jo_ID ; ça passe sans pb en local sur ton
Windows, mais quand tu mettras ça sur le serveur Linux de Free tu auras
des surprises... au passage, tu noteras que je simplifie l'écriture des
jointures en donnant des alias aux tables (J pour joueur, A pour
année_scolaire, etc.)


Tu as mille fois raison.


- selon l'ampleur temporelle de tes données, générer tous les couples
(Joueur, Année scolaire) peut t'amener à présenter des données idiotes,
comme "Machin, 1960-61 : 0 matchs", "Machin, 1961-62 : 0 matchs", etc.
pour un gars né en 1980. Dans ce cas, tu peux par exemple vouloir te
limiter aux années comprises entre la première et la dernière
participation. En supposant que le tri de tes as_id soit
chronologiquement valable, tu peux générer une table temporaire de ce
genre là :

CREATE TEMPORARY TABLE joueur_periode
SELECT jo_id, min(as_id) AS as_id_deb, max(as_id) AS as_id_fin
FROM joueur J
INNER JOIN classement_ELO C ON J.jo_id = C.jo_id
;

ensuite, dans la requête principale, tu remplaces le

joueur J
CROSS JOIN année_scolaire A

par qqch comme

joueur J
INNER JOIN joueur_periode JP ON J.jo_id = JP.jo_id
INNER JOIN année_scolaire A
ON A.as_id BETWEEN JP.as_id_deb AND JP.as_id_fin



Merci pour ces conseils, mais je n'en suis pas encore à ce stade.
--
jeb
http://jebissey.free.fr
Avatar
Antoun
Or, je suppose que si un joueur n'a participé à aucun match, il n'a pas
de classement ELO ? du coup, cela t'empêche de passer de Jouer à Année
scolaire.



Non, tous les joueurs on un classement ELO, on leur attribue même la
première fois qu'il joue une classement 'fictif' qui dépend de l'age.



OK. Donc c'est bcp plus simple que ce que je te disais.

Il faut donc que tu commences par générer tous les couples (Joueur,
Année scolaire) possibles avec un produit cartésien ; à partir de là, tu
fais des LEFT JOIN sur Evénement et Résultat.




(...)
En adaptant ta requête pour mySQL qui ne connaît pas CROSS JOIN j'arrive à :



MySQL, y compris dans la version 4.0 que propose Free, connaît CROSS
JOIN ! Ceci dit, tu peux effectivement le remplacer par une virgule,
techniquement c'est exactement la même chose.

SELECT jo_nom, jo_prénom, as_nom, count( * ) AS nb_matchs
FROM joueur AS J, année_scolaire AS A
LEFT JOIN évènement AS E ON A.as_id = E.év_ID
LEFT JOIN résultat AS R ON J.jo_id = R.jo_id
AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom
ORDER BY jo_nom, jo_prénom, as_nom



oups ! J'ai fait une coquille en écrivant A.as_id = E.év_ID. C'est bien
sûr A.as_id = E.as_ID

seconde erreur de ma part : il faut utiliser count(ré_id) et non
count(*) parce que count(*) compte les NULL.

ce qui donne, en passant par Classement_ELO :

SELECT jo_nom, jo_prénom, as_nom, count( ré_id ) AS nb_matchs
FROM joueur AS J
INNER JOIN classement_ELO AS C ON J.jo_id = C.jo_id
INNER JOIN année_scolaire AS A ON C.as_id = A.as_id
INNER JOIN évènement AS E ON A.as_id = E.as_ID
LEFT JOIN résultat AS R ON J.jo_id = R.jo_id AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom
ORDER BY jo_nom, jo_prénom, as_nom
Avatar
jibux
Antoun wrote:

Non, tous les joueurs on un classement ELO, on leur attribue même la
première fois qu'il joue une classement 'fictif' qui dépend de l'age.



OK. Donc c'est bcp plus simple que ce que je te disais.

MySQL, y compris dans la version 4.0 que propose Free, connaît CROSS
JOIN ! Ceci dit, tu peux effectivement le remplacer par une virgule,
techniquement c'est exactement la même chose.



VU

ce qui donne, en passant par Classement_ELO :

SELECT jo_nom, jo_prénom, as_nom, count( ré_id ) AS nb_matchs
FROM joueur AS J
INNER JOIN classement_ELO AS C ON J.jo_id = C.jo_id
INNER JOIN année_scolaire AS A ON C.as_id = A.as_id
INNER JOIN évènement AS E ON A.as_id = E.as_ID
LEFT JOIN résultat AS R ON J.jo_id = R.jo_id AND E.év_id = R.év_id
GROUP BY jo_nom, jo_prénom, as_nom
ORDER BY jo_nom, jo_prénom, as_nom



Effectivement c'est finalement vraiment simple et très clair.
Encore une fois merci pour toutes tes explications.

--
jeb
http://jebissey.free.fr