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 :

Pb de requête ou optimisation du schéma ?


Sujet :

Langage SQL

  1. #1
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 419
    Points
    419
    Par défaut Pb de requête ou optimisation du schéma ?
    Bonjour,

    Un ami veut mettre en place un petit systême de candidature.
    Les tables qu'il m'a fournies :

    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
    CREATE TABLE IF NOT EXISTS `candidatures` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `message` varchar(2000) NOT NULL,
      `email` varchar(60) NOT NULL,
      `ip` varchar(15) NOT NULL,
      `date` datetime NOT NULL,
      `login` varchar(50) NOT NULL,
      `traite` tinyint(1) NOT NULL DEFAULT '0',
      `resultat` tinyint(1) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
     
    CREATE TABLE IF NOT EXISTS `candidatures_votes` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `idmembre` int(6) NOT NULL,
      `id_candidature` int(5) NOT NULL,
      `vote` tinyint(1) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
    Pas de souci pour afficher les résultats des candidatures où l'on n'a déjà voté :

    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
    SELECT
        t.id,
        t.date,
        t.message,
        t.traite,
        t.resultat,
        t.login,
        p.idmembre,
        p.id_candidature,
        p.vote
    FROM
        candidatures AS t
    JOIN
        candidatures_votes AS p
    ON
        t.id = p.id_candidature
    WHERE
        t.date > DATE_ADD(NOW(), INTERVAL -2 DAY)
    AND
        t.traite = 0
    AND
        p.idmembre = id_session
    GROUP BY
        t.id
    ORDER BY
        t.date ASC

    Par contre pour afficher les candidatures ou l'on n'a pas encore voté j'ai essayé ç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
    SELECT
        t.id,
        t.date,
        t.message,
        t.traite,
        t.resultat,
        t.login,
        p.idmembre,
        p.id_candidature,
        p.vote
    FROM
        candidatures AS t
    JOIN
        candidatures_votes AS p
    ON
        t.id = p.id_candidature
    WHERE
        t.date > DATE_ADD(NOW(), INTERVAL -2 DAY)
    AND
        t.traite = 0
    AND
        p.idmembre != id_session
    GROUP BY
        t.id
    ORDER BY
        t.date ASC
    Mais évidemment ça ne fonctionne pas car il n'y a pas d'enfants dans la table candidatures_votes pour les candidatures où personne n'a encore voté et j'avoue que je tourne un peu en rond

    -> Est-il possible en une seule requête d'afficher les candidatures ou l'on n'a pas encore voté ?
    -> N'aurait-il pas été préférable créer une 3ème table "votes" et modifier la table candidatures_votes pour en faire uniquement une table de jointure ?

    Par avance merci.

  2. #2
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    Tu peux le faire en recherchant toutes les candidatures pour lesquels il n'y a pas de lignes dans candidatures_votes.
    Pour cela, regarde du coté du not exists

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 419
    Points
    419
    Par défaut
    Merci pour ta réponse jbrasselet,

    EXISTS et NOT EXISTS dans mes souvenirs c'est en effectuant une sous-requête qu'on les utilise ?

    Je vais regarder de ce côté.

  4. #4
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    C'est en effet avec une sous-requête

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 419
    Points
    419
    Par défaut
    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
    SELECT 
    	t.id, 
    	t.date, 
    	t.message, 
    	t.traite, 
    	t.resultat, 
    	t.login
    FROM
        candidatures AS t
    WHERE
        NOT EXISTS(
    		SELECT  
    			p.id_candidature
    		FROM 
    			candidatures_votes AS p	
    		WHERE
    			t.id = p.id_candidature)
    AND
        t.traite = 0	
    ORDER BY
        t.date ASC
    Merci encore pour ton aide, je suis sur la voix, mais cette requête me renvoit toutes les candidatures où personne n'a encore voté et non pas celle ou moi je n'ai pas voté, donc je suis pas encore bon là...

    Il faut donc que je fasse intervenir le champ idmembre mais je n'ai pas de sous-ensemble si je fais le fais intervenir dans la clause WHERE de la sous-requête. A moins de faire une jointure dans celle-ci ?

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Ajoute la restriction à ton idmembre dans la sous-requête.
    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
    SELECT 
        t.id, 
        t.date, 
        t.message, 
        t.traite, 
        t.resultat, 
        t.login
    FROM
        candidatures AS t
    WHERE
        NOT EXISTS(
            SELECT * -- Inutile de préciser des colonnes ici
            FROM 
                candidatures_votes AS p    
            WHERE
                t.id = p.id_candidature
                AND p.idmembre = 12
        )
        AND t.traite = 0    
    ORDER BY
        t.date ASC
    Traduction de la requête :
    "Sélectionner les candidatures pour lesquelles il n'existe pas de ligne dans la table des votes du membre 12 pour ces candidats "

    C'est ce que tu veux ?

  7. #7
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 419
    Points
    419
    Par défaut
    Merci CinePhil,

    je me suis embrouillé tout seul à force de chercher compliqué.
    C'est bien cette requête dont mon ami a besoin.

  8. #8
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    Dans ta sous-requete tu peux même faire un select 'X' comme ça tu ne parcourt pas les colonnes et tu optimise un brin tes performances.

  9. #9
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par jbrasselet Voir le message
    Dans ta sous-requete tu peux même faire un select 'X' comme ça tu ne parcourt pas les colonnes et tu optimise un brin tes performances.
    SELECT * va très bien. Dans ce cas, le SGBD ne cherche pas à ramener toutes les colonnes dans la sous-requête, il cherche seulement une ligne qui répond à la condition.

    [NOT] EXISTS est même le seul cas où on peut écrire SELECT * sans craindre de déclencher la guerre des étoiles !

  10. #10
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    OK, je ne savais pas.
    Merci de la précision

  11. #11
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 419
    Points
    419
    Par défaut
    Merci encore pour ces précisions. A priori je pensais aussi que le SELECT * renverrait toutes les colonnes...

    C'est normalisé au niveau des différents SGBDR ça ?

  12. #12
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 386
    Points
    18 386
    Par défaut
    Avec une jointure externe vous couvrez tous vos besoins avec une seule requête.

  13. #13
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 419
    Points
    419
    Par défaut
    J'avais pensé aussi à faire un OUTER JOIN mais je n'ai pas réussi à trouver la bonne requête, je vais regarder à nouveau de ce côté mais le gain en performance doit être limité, non ?

  14. #14
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 386
    Points
    18 386
    Par défaut
    Tout-à-fait, en terme de performances ça devrait être extrêmement proche.
    L'avantage c'est que la même requête répond à vos deux besoins :
    • les candidatures où l'on a déjà voté
    • les candidatures ou l'on n'a pas encore voté

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

Discussions similaires

  1. Requête SQL optimisée
    Par Shredder dans le forum Langage SQL
    Réponses: 7
    Dernier message: 07/02/2013, 02h03
  2. Problème de requête pas optimisée
    Par AlternantOracle dans le forum Requêtes
    Réponses: 2
    Dernier message: 12/01/2012, 11h52
  3. Requête SQL optimisée sur table d'index
    Par mill3d dans le forum Requêtes et SQL.
    Réponses: 13
    Dernier message: 25/08/2010, 12h05
  4. Requête corrélée : optimisation
    Par alband85 dans le forum Langage SQL
    Réponses: 9
    Dernier message: 17/07/2009, 23h55
  5. [Requête SQL] Optimisation de plusieurs UPDATE SET FROM
    Par dens19 dans le forum Développement
    Réponses: 6
    Dernier message: 13/03/2009, 16h51

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