IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Simplification d'une requête


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut Simplification d'une requête
    Bonjour,

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Quelque chose dans ce genre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 284
    Points : 12 986
    Points
    12 986
    Par défaut
    Bonjour,
    Tu peux faire une requête de ce style:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  4. #4
    Membre expérimenté
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Points : 1 717
    Points
    1 717
    Billets dans le blog
    6
    Par défaut
    peux tu nous poster des exemples des données?

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 115
    Points : 28 480
    Points
    28 480
    Par défaut
    Comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Je verrais bien un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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)

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par Yanika_bzh Voir le message
    Quelque chose dans ce genre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Tu peux faire une requête de ce style:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  10. #10
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    Comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 284
    Points : 12 986
    Points
    12 986
    Par défaut
    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.

  12. #12
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Et ma requête tu t'en fous ?

  13. #13
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Je verrais bien un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  14. #14
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par DomIII Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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;

  15. #15
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    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.

  16. #16
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

  17. #17
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    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...

  18. #18
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

  19. #19
    Membre expérimenté
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Points : 1 717
    Points
    1 717
    Billets dans le blog
    6
    Par défaut
    Tu peux même généraliser ta requête en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  20. #20
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2007
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 163
    Points : 90
    Points
    90
    Par défaut
    Merveilleux !

    Merci pour cette requête généralisée, c'est parfait.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Simplification d'une requête
    Par Poulain dans le forum Requêtes
    Réponses: 5
    Dernier message: 21/09/2010, 01h25
  2. Simplification d'une requête
    Par edogawa dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 20/07/2010, 08h56
  3. simplification d'une requête
    Par Jasmine80 dans le forum Requêtes
    Réponses: 12
    Dernier message: 20/04/2009, 22h45
  4. Simplification d'une requête SQL
    Par nicou50 dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 07/09/2006, 07h37
  5. Simplification d'une requête UNION
    Par eautret dans le forum Langage SQL
    Réponses: 6
    Dernier message: 18/01/2005, 15h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo