Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/09/2011, 13h42   #1
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Par défaut Simplification d'une requête

Bonjour,

Je voudrais "simplifier" la requête suivante sur MYSQL 5:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
-- SYNTHESE DES MATCHES D'UNE EQUIPE
SELECT ep.nom, victoires " G ", nuls " N ", defaites " P ", 3 * victoires + nuls "PTS"
FROM
	equipe ep,
	(
		(
		SELECT count(*) AS victoires 
		FROM rencontre r, equipe e
		WHERE
			(
/* ici */			e.oid = 15 AND
			r.oid_equipe_r = e.oid AND
			r.score_r <> -1 AND
			r.score_r > r.score_v
			) 
			OR
			(
/* ici */			e.oid = 15 AND
			r.oid_equipe_v = e.oid AND
			r.score_v <> -1 AND
			r.score_v > r.score_r
			)
		)
	) victoires1,
	(
		(
		SELECT count(*) AS nuls 
		FROM rencontre r, equipe e
		WHERE
/*ici */			e.oid = 15 AND
			(r.oid_equipe_r = e.oid OR r.oid_equipe_v = e.oid) AND
			r.score_r <> -1 AND
			r.score_r = r.score_v
		)
	) nuls1,
	(
		(
		SELECT count(*) AS defaites 
		FROM rencontre r, equipe e
		WHERE
			(
/* ici */			e.oid = 15 AND
			r.oid_equipe_r = e.oid AND
			r.score_r <> -1 AND
			r.score_r < r.score_v
			)
			OR
			(
/* ici */			e.oid = 15 AND
			r.oid_equipe_v = e.oid AND
			r.score_v <> -1 AND
			r.score_r > r.score_v
			)
		)
	) defaites1
WHERE
	ep.oid = 15;
Je fais une requête dans une base gérant des championnats de sports collectifs. Cependant, cette requête met en "dur" l'OID de l'équipe dans les sous-requêtes, ce qui ne me plaît pas.

Je voudrais simplement mettre une seule fois la clause, c'est-à-dire à la dernière ligne (ep.oid = 15) et éliminer les autres, là où j'ai mis le commentaire /* ici */

J'ai essayé de mettre dans les sous-requêtes mais SQL me donne une erreur, ep est l'alias de la table EQUIPE dans le from de la requête principale :
Code :
ERROR 1054 (42S22): Unknown COLUMN 'ep.oid' IN 'where clause'
Quelqu'un pourrait-il me dire s'il existe un moyen pour éliminer l'OID en dur dans les sous-requêtes pour ne le faire figurer qu'une seule et unique fois dans la clause de la requête principale ?

Merci par avance.
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 14h02   #2
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
Quelque chose dans ce genre ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SELECT Tab.nom, Tab.Victoires " G ", Tab.Nuls " N ", Tab.Defaites " P ", 3 * Tab.victoires + Tab.nuls "PTS"
FROM
(
SELECT
	ep.nom, 
	case WHEN 
		(e.oid = r.oid_equipe_r AND r.score_r>r.score_v) OR (e.oid = r.oid_equipe_v AND r.score_v>r.score_r)
	     THEN 
		SUM(1)
	end AS Victoires,
	case  WHEN 
		(r.score_r = r.score_v)
	      THEN	
	     	SUM(1)
	end AS Nuls,
	case WHEN (e.oid = r.oid_equipe_r AND r.score_r<r.score_r) OR (e.oid = r.oid_equipe_v AND r.score_r<r.score_v)
	      THEN
		SUM(1)
	end AS Defaites
 
FROM
	equipe ep 
INNER JOIN 
	rencontre r ON (ep.oid = r.oid_equipe_r OR  ep.oid = r.oid_equipe_v)
WHERE
	r.score_v<>-1 AND r.score_r<>-1
	AND ep.oid = 15
) Tab
A tester et adapter.

Bon courage
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 14h05   #3
Membre Expert
 
Homme
Responsable de service informatique
Inscription : janvier 2009
Messages : 1 092
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Boutique - Magasin

Informations forums :
Inscription : janvier 2009
Messages : 1 092
Points : 1 898
Points : 1 898
Bonjour,
Tu peux faire une requête de ce style:
Code SQL :
1
2
3
4
5
6
 
SELECT equipe.nom,sum(case when victoire then 1 else 0 end) AS victoire, sum(case when defaite then 1 else 0 end) AS defaite
FROM equipe
INNER JOIN rencontre ON rencontre.oid_equipe_r = equipe.oid OR rencontre.oid_equipe_v = equipe.oid
WHERE les autres conditions...
GROUP BY equipe.nom
en remplaçant victoire/defaite par la condition qui va bien.

Tatayo.
tatayo est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 14h15   #4
Membre éclairé
 
Avatar de boussafi
 
Homme
Ingénieur développement logiciels
Inscription : septembre 2007
Messages : 342
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Algérie

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Industrie

Informations forums :
Inscription : septembre 2007
Messages : 342
Points : 397
Points : 397
Envoyer un message via Yahoo à boussafi Envoyer un message via Skype™ à boussafi
peux tu nous poster des exemples des données?
boussafi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 14h22   #5
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 446
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 446
Points : 7 543
Points : 7 543
Comme ça ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- SYNTHESE DES MATCHES D'UNE EQUIPE
SELECT  ep.nom
    ,   victoires   " G "
    ,   nuls        " N "
    ,   defaites    " P "
    ,   3 * victoires + nuls "PTS"
FROM    equipe ep
    INNER JOIN
        (   SELECT  e.oid
                ,   COUNT(*)    AS victoires
            FROM    rencontre   r
                INNER JOIN
                    equipe      e
                    ON  (   r.oid_equipe_r  = e.oid
                        AND r.score_r       <> -1
                        AND r.score_r       > r.score_v
                        )
                    OR  (   r.oid_equipe_v  = e.oid
                        AND r.score_v       <> -1
                        AND r.score_v       > r.score_r
                        )
        )   victoires1
        ON  ep.oid  = victoires1.oid
    INNER JOIN
        (   SELECT  e.oid
                ,   COUNT(*) AS nuls
            FROM    rencontre   r
                INNER JOIN
                    equipe      e
                    ON  (   r.oid_equipe_r  = e.oid
                        OR  r.oid_equipe_v  = e.oid
                        )
            WHERE   r.score_r   <> -1
                AND r.score_r   = r.score_v
        )   nuls1
        ON  ep.oid  = nuls1.oid
    INNER JOIN
        (   SELECT  e.oid
                ,   COUNT(*)    AS defaites
            FROM    rencontre   r
                INNER JOIN
                    equipe      e
            WHERE   (   r.oid_equipe_r  = e.oid 
                    AND r.score_r       <> -1 
                    AND r.score_r       < r.score_v
                    )
                OR  (   r.oid_equipe_v  = e.oid
                    AND r.score_v       <> -1 
                    AND r.score_r       > r.score_v
                    )
        )   defaites1
        ON  ep.oid  = defaites1.oid
WHERE   ep.oid = 15
;
Edit : Grilled
__________________
Modérateur Langage SQL
Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
N'oubliez pas le bouton et pensez aux balises [code]
Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 14h31   #6
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Je verrais bien un truc du genre :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SELECT 
  e.nom, 
  sum(case when re.resultat = 1 then 1 else 0) " G ",
  sum(case when re.resultat = 0 then 1 else 0) " N ",
  sum(case when re.resultat = -1 then 1 else 0) " P ",
  sum(case when re.resultat = 1 then 3 when re.resultat = 0 then 1 else 0) " PTS "
FROM equipe e
INNER JOIN 
(
  SELECT e.oid, sign(r.score_r - r.score_v) * (case when e.oid = r.oid_equipe_r then 1 else -1 end) resultat
  FROM equipe e
  INNER JOIN rencontre r ON r.oid_equipe_r OR e.oid = r.oid_equipe_v
) resultat_equipe re ON re.odi = e.oid
WHERE e.oid = 15;
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h20   #7
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Citation:
Envoyé par boussafi Voir le message
peux tu nous poster des exemples des données?
Bonjour,

Pour faire simple, j'ai un échantillon du championnat de football de L1 de cette année.

La création des deux tables :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE DATABASE CHAMP_FOOT_FR_L1_2011_2012;
 
USE CHAMP_FOOT_FR_L1_2011_2012;
 
CREATE TABLE IF NOT EXISTS EQUIPE
(
OID INT PRIMARY KEY,
NOM VARCHAR(50) NOT NULL
);
 
CREATE TABLE IF NOT EXISTS RENCONTRE
(
OID INT PRIMARY KEY,
OID_EQUIPE_R INT,
OID_EQUIPE_V INT,
SCORE_R INT DEFAULT 0,
SCORE_V INT DEFAULT 0,
DATE_MATCH DATE NOT NULL,
JOURNEE INT,
CONSTRAINT REGLE_1 FOREIGN KEY (OID_EQUIPE_R) REFERENCES EQUIPE(OID),
CONSTRAINT REGLE_2 FOREIGN KEY (OID_EQUIPE_V) REFERENCES EQUIPE(OID)
);
Remplissage de la table EQUIPE :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
INSERT INTO EQUIPE (OID, NOM)
VALUES
	("1", "AJACCIO"),
	("2", "AUXERRE"),
	("3", "BORDEAUX"),
	("4", "BREST"),
	("5", "CAEN"),
	("6", "DIJON"),
	("7", "EVIAN"),
	("8", "LILLE"),
	("9", "LORIENT"),
	("10", "LYON"),
	("11", "MARSEILLE"),
	("12", "MONTPELLIER"),
	("13", "NANCY"),
	("14", "NICE"),
	("15", "PARIS SAINT-GERMAIN"),
	("16", "RENNES"),
	("17", "SAINT-ETIENNE"),
	("18", "SOCHAUX"),
	("19", "TOULOUSE"),
	("20", "VALENCIENNES");
Et celui de la table RENCONTRE (comprend 4 journées jouées et la 5e non disputée à ce jour) :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
-- JOURNEE 1
INSERT INTO RENCONTRE (OID, OID_EQUIPE_R, OID_EQUIPE_V, SCORE_R, SCORE_V, DATE_MATCH, JOURNEE)
VALUES
	("1", "11", "18", "2", "2", "2011/08/06", "1"),
	("2", "15", "9", "0", "1", "2011/08/06", "1"),
	("3", "1", "19", "0", "2", "2011/08/06", "1"),
	("4", "14", "10", "1", "3", "2011/08/06", "1"),
	("5", "13", "8", "1", "1", "2011/08/06", "1"),
	("6", "5", "20", "1", "0", "2011/08/06", "1"),
	("7", "12", "2", "3", "1", "2011/08/06", "1"),
	("8", "4", "7", "2", "2", "2011/08/06", "1"),
	("9", "6", "16", "1", "5", "2011/08/07", "1"),
	("10", "3", "17", "1", "2", "2011/08/07", "1");
 
-- JOURNEE 2
INSERT INTO RENCONTRE (OID, OID_EQUIPE_R, OID_EQUIPE_V, SCORE_R, SCORE_V, DATE_MATCH, JOURNEE)
VALUES
	("11", "15", "16", "1", "1", "2011/08/13", "2"),
	("12", "10", "1", "1", "1", "2011/08/13", "2"),
	("13", "19", "6", "2", "0", "2011/08/13", "2"),
	("14", "17", "13", "1", "0", "2011/08/13", "2"),
	("15", "18", "5", "1", "2", "2011/08/13", "2"),
	("16", "9", "3", "1", "1", "2011/08/13", "2"),
	("17", "20", "4", "0", "0", "2011/08/13", "2"),
	("18", "2", "11", "2", "2", "2011/08/14", "2"),
	("19", "7", "14", "1", "0", "2011/08/14", "2"),
	("20", "8", "12", "0", "1", "2011/08/14", "2");
 
-- JOURNEE 3
INSERT INTO RENCONTRE (OID, OID_EQUIPE_R, OID_EQUIPE_V, SCORE_R, SCORE_V, DATE_MATCH, JOURNEE)
VALUES
	("21", "14", "19", "1", "1", "2011/08/20", "3"),
	("22", "5", "8", "1", "2", "2011/08/20", "3"),
	("23", "4", "10", "1", "1", "2011/08/20", "3"),
	("24", "6", "9", "2", "0", "2011/08/20", "3"),
	("25", "3", "2", "1", "1", "2011/08/20", "3"),
	("26", "1", "7", "1", "1", "2011/08/20", "3"),
	("27", "12", "16", "4", "0", "2011/08/21", "3"),
	("28", "13", "18", "1", "2", "2011/08/21", "3"),
	("29", "15", "20", "2", "1", "2011/08/21", "3"),
	("30", "11", "17", "0", "0", "2011/08/21", "3");
 
-- JOURNEE 4 
INSERT INTO RENCONTRE (OID, OID_EQUIPE_R, OID_EQUIPE_V, SCORE_R, SCORE_V, DATE_MATCH, JOURNEE)
VALUES
	("31", "7", "6", "0", "1", "2011/08/27", "4"),
	("32", "9", "13", "2", "1", "2011/08/27", "4"),
	("33", "14", "4", "0", "0", "2011/08/27", "4"),
	("34", "20", "3", "1", "2", "2011/08/27", "4"),
	("35", "2", "1", "4", "1", "2011/08/27", "4"),
	("36", "10", "12", "2", "1", "2011/08/27", "4"),
	("37", "19", "15", "1", "3", "2011/08/28", "4"),
	("38", "18", "17", "2", "1", "2011/08/28", "4"),
	("39", "16", "5", "3", "2", "2011/08/28", "4"),
	("40", "8", "11", "3", "2", "2011/08/28", "4");
 
-- JOURNEE 5
INSERT INTO RENCONTRE (OID, OID_EQUIPE_R, OID_EQUIPE_V, SCORE_R, SCORE_V, DATE_MATCH, JOURNEE)
VALUES
	("41", "6", "10", "-1", "-1", "2011/09/10", "5"),
	("42", "5", "19", "-1", "-1", "2011/09/10", "5"),
	("43", "18", "9", "-1", "-1", "2011/09/10", "5"),
	("44", "17", "8", "-1", "-1", "2011/09/10", "5"),
	("45", "3", "7", "-1", "-1", "2011/09/10", "5"),
	("46", "1", "20", "-1", "-1", "2011/09/10", "5"),
	("47", "11", "16", "-1", "-1", "2011/09/10", "5"),
	("48", "12", "14", "-1", "-1", "2011/09/11", "5"),
	("49", "13", "2", "-1", "-1", "2011/09/11", "5"),
	("50", "15", "4", "-1", "-1", "2011/09/11", "5");
Donc, pour prendre l'équipe dont l'OID est 1 (AJACCIO), voilà ce que l'exécution donne :

Code :
1
2
3
4
5
6
+---------+---+---+---+-----+
| nom     | G | N | P | PTS |
+---------+---+---+---+-----+
| AJACCIO | 0 | 2 | 2 |   2 |
+---------+---+---+---+-----+
1 row IN SET, 3 warnings (0.00 sec)
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h25   #8
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Citation:
Envoyé par Yanika_bzh Voir le message
Quelque chose dans ce genre ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SELECT Tab.nom, Tab.Victoires " G ", Tab.Nuls " N ", Tab.Defaites " P ", 3 * Tab.victoires + Tab.nuls "PTS"
FROM
(
SELECT
	ep.nom, 
	case WHEN 
		(e.oid = r.oid_equipe_r AND r.score_r>r.score_v) OR (e.oid = r.oid_equipe_v AND r.score_v>r.score_r)
	     THEN 
		SUM(1)
	end AS Victoires,
	case  WHEN 
		(r.score_r = r.score_v)
	      THEN	
	     	SUM(1)
	end AS Nuls,
	case WHEN (e.oid = r.oid_equipe_r AND r.score_r<r.score_r) OR (e.oid = r.oid_equipe_v AND r.score_r<r.score_v)
	      THEN
		SUM(1)
	end AS Defaites
 
FROM
	equipe ep 
INNER JOIN 
	rencontre r ON (ep.oid = r.oid_equipe_r OR  ep.oid = r.oid_equipe_v)
WHERE
	r.score_v<>-1 AND r.score_r<>-1
	AND ep.oid = 15
) Tab
A tester et adapter.

Bon courage


Merci beaucoup, ça fonctionne à merveilles !

Voici le code adapté :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SELECT Tab.nom, sum(Tab.Victoires) " G ", sum(Tab.Nuls) " N ", sum(Tab.Defaites) " P ", sum(3 * Tab.victoires + Tab.nuls) "PTS"
FROM
(
SELECT
	e.nom, 
	case WHEN 
		(e.oid = r.oid_equipe_r AND r.score_r>r.score_v) OR (e.oid = r.oid_equipe_v AND r.score_v>r.score_r) 
	     THEN 
		 1 else 0
	end AS Victoires,
	case  WHEN 
		(r.score_r = r.score_v)
	      THEN	
	     1 else 0
	end AS Nuls,
	case WHEN (e.oid = r.oid_equipe_r AND r.score_r<r.score_r) OR (e.oid = r.oid_equipe_v AND r.score_r<r.score_v)
	      THEN
		1 else 0
	end AS Defaites
FROM
	equipe e
INNER JOIN 
	rencontre r ON (e.oid = r.oid_equipe_r OR  e.oid = r.oid_equipe_v)
WHERE
	r.score_v<>-1 AND r.score_r<>-1
	AND e.oid = 15
) Tab;
Cela dit, j'avoue en toute honnêteté que je ne comprends pas tout dans cette reformulation. Je vais consulter et éplucher la doc MySQL pour percer les secrets de cette requête.

J'aurai ainsi beaucoup appris aujourd'hui
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h30   #9
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Citation:
Envoyé par tatayo Voir le message
Bonjour,
Tu peux faire une requête de ce style:
Code SQL :
1
2
3
4
5
6
 
SELECT equipe.nom,sum(case when victoire then 1 else 0 end) AS victoire, sum(case when defaite then 1 else 0 end) AS defaite
FROM equipe
INNER JOIN rencontre ON rencontre.oid_equipe_r = equipe.oid OR rencontre.oid_equipe_v = equipe.oid
WHERE les autres conditions...
GROUP BY equipe.nom
en remplaçant victoire/defaite par la condition qui va bien.

Tatayo.
Bonjour Tatayo,

Merci pour ton aide. Cependant, je ne vois pas comment corréler les conditions de victoire. Par exemple, comment rattacher la condition suivante à "victoire" ?
Code :
1
2
3
equipe.oid = rencontre.oid_equipe_r AND
rencontre.score_r > rencontre.score_v AND
rencontre.score_r <> -1
Pourrais-tu m'éclairer ou m'orienter ?

Merci par avance.
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h35   #10
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Citation:
Envoyé par al1_24 Voir le message
Comme ça ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- SYNTHESE DES MATCHES D'UNE EQUIPE
SELECT  ep.nom
    ,   victoires   " G "
    ,   nuls        " N "
    ,   defaites    " P "
    ,   3 * victoires + nuls "PTS"
FROM    equipe ep
    INNER JOIN
        (   SELECT  e.oid
                ,   COUNT(*)    AS victoires
            FROM    rencontre   r
                INNER JOIN
                    equipe      e
                    ON  (   r.oid_equipe_r  = e.oid
                        AND r.score_r       <> -1
                        AND r.score_r       > r.score_v
                        )
                    OR  (   r.oid_equipe_v  = e.oid
                        AND r.score_v       <> -1
                        AND r.score_v       > r.score_r
                        )
        )   victoires1
        ON  ep.oid  = victoires1.oid
    INNER JOIN
        (   SELECT  e.oid
                ,   COUNT(*) AS nuls
            FROM    rencontre   r
                INNER JOIN
                    equipe      e
                    ON  (   r.oid_equipe_r  = e.oid
                        OR  r.oid_equipe_v  = e.oid
                        )
            WHERE   r.score_r   <> -1
                AND r.score_r   = r.score_v
        )   nuls1
        ON  ep.oid  = nuls1.oid
    INNER JOIN
        (   SELECT  e.oid
                ,   COUNT(*)    AS defaites
            FROM    rencontre   r
                INNER JOIN
                    equipe      e
            WHERE   (   r.oid_equipe_r  = e.oid 
                    AND r.score_r       <> -1 
                    AND r.score_r       < r.score_v
                    )
                OR  (   r.oid_equipe_v  = e.oid
                    AND r.score_v       <> -1 
                    AND r.score_r       > r.score_v
                    )
        )   defaites1
        ON  ep.oid  = defaites1.oid
WHERE   ep.oid = 15
;
Edit : Grilled
Bonjour al1_24,

L'exécution de cette belle requête me donne :
Code :
Empty SET, 3 warnings (0.00 sec)
Je regarde afin d'essayer de trouver ce qui ne va pas. Cependant, mon niveau en SQL est plutôt basique... Je n'ai jamais utilisé INNER JOIN, je vais donc éplucher la documentation de (My)SQL.

Merci pour ton aide, je reste certain qu'il y a un simple "truc" à corriger pour que cela fonctionne.
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h37   #11
Membre Expert
 
Homme
Responsable de service informatique
Inscription : janvier 2009
Messages : 1 092
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Boutique - Magasin

Informations forums :
Inscription : janvier 2009
Messages : 1 092
Points : 1 898
Points : 1 898
En fait Yanika_bzh a donné la réponse complète... Je pensais qu'on pouvait la faire sans sous-requête, mais à priori non.

Tatayo.
tatayo est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h38   #12
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Et ma requête tu t'en fous ?
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h48   #13
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Citation:
Envoyé par StringBuilder Voir le message
Je verrais bien un truc du genre :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SELECT 
  e.nom, 
  sum(case when re.resultat = 1 then 1 else 0) " G ",
  sum(case when re.resultat = 0 then 1 else 0) " N ",
  sum(case when re.resultat = -1 then 1 else 0) " P ",
  sum(case when re.resultat = 1 then 1 when re.resultat = 0 then 1 else 0) " PTS "
FROM equipe e
INNER JOIN 
(
  SELECT e.oid, sign(r.score_r - r.score_v) * (case when e.oid = r.oid_equipe_r then 1 else -1 end) resultat
  FROM equipe e
  INNER JOIN rencontre r ON r.oid_equipe_r OR e.oid = r.oid_equipe_v
) resultat_equipe re ON re.odi = e.oid
WHERE e.oid = 15;
Bonjour StringBuilder,

merci pour ta réponse. Comme je le disais plus haut, je suis débutant en SQL et n'ai jamais manipulé INNER JOIN pour faire de telles requêtes. J'ai essayé ta requête, SQL me signale une erreur de syntaxe :

Code :
1
2
3
4
5
6
    -> WHERE e.oid = 15;
ERROR 1064 (42000): You have an error IN your SQL syntax; CHECK the manual that corresponds TO your MySQL server version FOR the RIGHT syntax TO USE near 
') " G ",
  sum(case when re.resultat = 0 then 1 else 0) " N ",
  sum(case when r' 
at line 3
Je regarde la ligne 3, je ne vois pas d'erreur de syntaxe... mais mes connaissances sont limitées.
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h55   #14
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Citation:
Envoyé par DomIII Voir le message
Code :
1
2
3
4
5
6
    -> WHERE e.oid = 15;
ERROR 1064 (42000): You have an error IN your SQL syntax; CHECK the manual that corresponds TO your MySQL server version FOR the RIGHT syntax TO USE near 
') " G ",
  sum(case when re.resultat = 0 then 1 else 0) " N ",
  sum(case when r' 
at line 3
Je regarde la ligne 3, je ne vois pas d'erreur de syntaxe... mais mes connaissances sont limitées.
Oups, j'ai oublié de mettre un "end" avant le ")" de chacun des sum() du select
=> du coup le case n'est pas terminé et ça plante.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SELECT 
  e.nom, 
  sum(case when re.resultat = 1 then 1 else 0 end) " G ",
  sum(case when re.resultat = 0 then 1 else 0 end) " N ",
  sum(case when re.resultat = -1 then 1 else 0 end) " P ",
  sum(case when re.resultat = 1 then 3 when re.resultat = 0 then 1 else 0 end) " PTS "
FROM equipe e
INNER JOIN 
(
  SELECT e.oid, sign(r.score_r - r.score_v) * (case when e.oid = r.oid_equipe_r then 1 else -1 end) resultat
  FROM equipe e
  INNER JOIN rencontre r ON r.oid_equipe_r OR e.oid = r.oid_equipe_v
) resultat_equipe re ON re.odi = e.oid
WHERE e.oid = 15;
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h02   #15
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
Citation:
Envoyé par tatayo Voir le message
En fait Yanika_bzh a donné la réponse complète... Je pensais qu'on pouvait la faire sans sous-requête, mais à priori non.

Tatayo.
Il est possible de faire sans sous requete, mais il faudrait doubler les conditions (case when) dans le SELECT afin de les utiliser pour le calcul global des points. J'ai trouvé plus lisible de passer par une sous requete, qui ne devrait pas penaliser les performances de l'appli.
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h28   #16
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Citation:
Envoyé par StringBuilder Voir le message
Oups, j'ai oublié de mettre un "end" avant le ")" de chacun des sum() du select
=> du coup le case n'est pas terminé et ça plante.
Mais non, mais non, je ne t'ai pas oublié... Le temps que je réponde à tout le monde

En tout cas, merci pour ton intervention.

Bien, encore une petite erreur de syntaxe, sachant que je crois avoir repéré deux petites fautes :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT 
  e.nom, 
  sum(case when re.resultat = 1 then 1 else 0 end) " G ",
  sum(case when re.resultat = 0 then 1 else 0 end) " N ",
  sum(case when re.resultat = -1 then 1 else 0 end) " P ",
  sum(case when re.resultat = 1 then 3 when re.resultat = 0 then 1 else 0 end) " PTS "
FROM equipe e
INNER JOIN 
(
  SELECT e.oid, sign(r.score_r - r.score_v) * (case when e.oid = r.oid_equipe_r then 1 else -1 end) resultat
  FROM equipe e
  INNER JOIN rencontre r ON r.oid_equipe_r = e.oid OR e.oid = r.oid_equipe_v /* ai ajouté = e.oid avant le OR */
) resultat_equipe re ON re.oid = e.oid /* corrigé ODI par OID */
WHERE 
	e.oid = 15;
Malheureusement, une erreur persiste :
Code :
1
2
3
4
5
6
ERROR 1064 (42000): You have an error IN your SQL syntax; CHECK the manual that corresponds TO your MySQL server version FOR the RIGHT syntax TO USE near 
're ON
 re.oid = e.oid
WHERE
        e.oid = 15' 
at line 13
Ça avance, petit à petit, mais sûrement !
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h34   #17
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
hmpf :o

vire le "resultat_equipe"

l'alias "re" suffit, pas la peine de l'aliser deux fois.

désolé

je suis pas bien réveillé ça fait peur...
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h44   #18
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Par défaut Supeeeeeeeeeeeer !

Citation:
Envoyé par StringBuilder Voir le message
hmpf :o

vire le "resultat_equipe"

l'alias "re" suffit, pas la peine de l'aliser deux fois.

désolé

je suis pas bien réveillé ça fait peur...
NICKEEEEEEEEEEEEEEEEEEEL !!!

Pour s'en convaincre, voici la réponse (OID = 15) :

Code :
1
2
3
4
5
6
+---------------------+------+------+------+------+
| nom                 | G    | N    | P    | PTS  |
+---------------------+------+------+------+------+
| PARIS SAINT-GERMAIN |    2 |    1 |    1 |    7 |
+---------------------+------+------+------+------+
1 row IN SET, 4 warnings (0.00 sec)
Pas de doute, le réveil a sonné pour toi Je m'incline humblement devant vous tous pour cette aide efficace. A ma charge de me renforcer en SQL pour comprendre cette façon un peu plus complexe de faire des sous-requêtes.

Je me suis permis d'ajouter une petite condition afin de ne prendre en compte que les matches joués, c'est-à-dire :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT 
  e.nom, 
  sum(case when re.resultat = 1 then 1 else 0 end) " G ",
  sum(case when re.resultat = 0 then 1 else 0 end) " N ",
  sum(case when re.resultat = -1 then 1 else 0 end) " P ",
  sum(case when re.resultat = 1 then 3 when re.resultat = 0 then 1 else 0 end) " PTS "
FROM equipe e
INNER JOIN 
(
  SELECT e.oid, sign(r.score_r - r.score_v) * (case when e.oid = r.oid_equipe_r then 1 else -1 end) resultat
  FROM equipe e
  INNER JOIN rencontre r ON (r.oid_equipe_r = e.oid OR e.oid = r.oid_equipe_v) AND r.score_v <> -1 /* AJOUT CONDITION MATCH JOUE */
) re ON re.oid = e.oid
WHERE 
	e.oid = 15;
Voilà qui fait bien mes affaires.

Merci encore !
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/09/2011, 09h57   #19
Membre éclairé
 
Avatar de boussafi
 
Homme
Ingénieur développement logiciels
Inscription : septembre 2007
Messages : 342
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Algérie

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Industrie

Informations forums :
Inscription : septembre 2007
Messages : 342
Points : 397
Points : 397
Envoyer un message via Yahoo à boussafi Envoyer un message via Skype™ à boussafi
Tu peux même généraliser ta requête en faisant :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT 
  e.nom, 
  sum(case when re.resultat = 1 then 1 else 0 end) " G ",
  sum(case when re.resultat = 0 then 1 else 0 end) " N ",
  sum(case when re.resultat = -1 then 1 else 0 end) " P ",
  sum(case when re.resultat = 1 then 3 when re.resultat = 0 then 1 else 0 end) " PTS "
FROM equipe e
INNER JOIN 
(
  SELECT e.oid, sign(r.score_r - r.score_v) * (case when e.oid = r.oid_equipe_r then 1 else -1 end) resultat
  FROM equipe e
  INNER JOIN rencontre r ON (r.oid_equipe_r = e.oid OR e.oid = r.oid_equipe_v) AND r.score_v <> -1 /* AJOUT CONDITION MATCH JOUE */
) re ON re.oid = e.oid
 
  GROUP BY e.nom
boussafi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2011, 10h23   #20
Nouveau Membre du Club
 
Homme
Développeur Java
Inscription : mars 2007
Messages : 111
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Java

Informations forums :
Inscription : mars 2007
Messages : 111
Points : 32
Points : 32
Merveilleux !

Merci pour cette requête généralisée, c'est parfait.
DomIII est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h57.


 
 
 
 
Partenaires

Hébergement Web