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 :

Problème avec WHERE


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2012
    Messages : 7
    Points : 4
    Points
    4
    Par défaut Problème avec WHERE
    Bonsoir,

    Voila, mon problème est assez simple, mais je n'arrive pas à le résoudre

    J'ai 3 Tables:

    Ouvrage(ou_id, titre, genre, année)
    Auteur(aid, nom, prénom, pseudo)
    a_ecrit(ou_id, aid, rôle)

    mon problème concerne le rôle, sachant que ce dernier n'a pour valeur que ("Auteur", "Dessinateur")
    Je voudrais sélectionner les ouvrages pour lesquels l'auteur est aussi le dessinateur.

    Sous SQLdeveloper, je fais ceci:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select ouvrage.titre 
    from ouvrage, a_ecrit 
    where ouvrage.ou_id = a_ecrit.ou_id 
        and a_ecrit.rôle = 'Auteur' 
        and a_ecrit.rôle = 'Dessinateur';
    Mais ça ne marche pas, la requête est syntaxiquement correcte mais ça ne renvoie rien, pourtant dans mon jeu d'essai, il y'a effectivement un ouvrage(ou_id) pour lequel le même auteur(aid) est Auteur et Dessinateur.
    Voici mon jeu d'essai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    OU_ID | AID | RÔLE
    -------
    1          1      Auteur
    2          2      Auteur
    2          1      Dessinateur
    1          1      Dessinateur
    me suis je trompé? que devrais je changer? Merci.

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mast3r,


    Si l’on vous suit, pour chaque ligne de la table :
    Si la personne qui figure dans cette ligne est auteur, il faut qu’elle y soit aussi dessinateur, ce qui ne fonctionne pas puisque que cet autre rôle est forcément dans une autre ligne de la table...
    Il faut que vous procédiez comme si une 1re table contenait les auteurs et une autre table les dessinateurs : si Albert figure dans les deux tables alors c’est bon.

    Comme vous n’avez en réalité qu’une seule table, vous utiliserez une auto-jointure (x et y symbolisent les deux tables hypothétiques) :


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM   a_ecrit AS x INNER JOIN a_ecrit AS y ON x.ou_id = y.ou_id AND x.AID = y.AID
    WHERE  x.RÔLE = 'Dessinateur' AND y.RÔLE = 'Auteur' ;
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    AU fait ce serait bien d'utiliser la syntaxe sur les jointures en place depuis plus de 20 ans


    un autre solution consisterait à chercher les auteurs qui ont 2 casquettes au travers d'une sous-requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT a.aid, COUNT(*)
    FROM auteur a
       INNER JOIN a_ecrit e ON e.aid = a.aid
    GROUP BY a.aid, a.nom 
    HAVING COUNT(*) = 2
    Ensuite utiliser cette requête pour sélectionner les ouvrages concernés (si telle est l'objectif)
    Merci d'ajouter un sur les tags qui vous ont aidé

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonjour,


    Citation Envoyé par dehorter olivier Voir le message
    ce serait bien d'utiliser la syntaxe sur les jointures en place depuis plus de 20 ans
    Pourriez-vous expliquer ce qui au plan de la syntaxe ne vous convient pas ? Ne dites quand même pas que vous voudriez qu’on mélange jointure et restriction.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Bonjour,

    Pourriez-vous expliquer ce qui au plan de la syntaxe ne vous convient pas ? Ne dites quand même pas que vous voudriez qu’on mélange jointure et restriction.
    je ne parlais pas de votre requête, mais de celle de mast3r
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT ouvrage.titre 
    FROM ouvrage, a_ecrit 
    WHERE ouvrage.ou_id = a_ecrit.ou_id 
    ....
    et au que non
    Merci d'ajouter un sur les tags qui vous ont aidé

  6. #6
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par dehorter olivier Voir le message
    un autre solution consisterait à chercher les auteurs qui ont 2 casquettes au travers d'une sous-requête
    Attention, votre requête ne répond pas à la demande :
    Supposons que M. Albert soit l’auteur et l’illustrateur de l’ouvrage « Inner join et NULL pour les nuls » et qu’il soit aussi l’auteur de l’ouvrage « Tout sur la norme SQL ». Le résultat du comptage est en l’occurrence > 2, donc M. Albert ne figure pas dans le résultat. Qui plus est, si M. Bernard est l’auteur de « L’union de la carpe et du lapin » et l’illustrateur de « Qu’est-ce qu’Having ? » et n’a rien commis d’autre, alors il figure à tort dans le résultat...
    Accessoirement, votre requête n’est pas emboîtée (SELECT mis entre parenthèses), donc selon la norme SQL 2003 elle n’est pas une sous-requête (subquery).


    Citation Envoyé par dehorter olivier Voir le message
    ne parlais pas de votre requête, mais de celle de mast3r
    La jointure proposée par mast3r est tout à fait respectable. Au point que, paradoxe ! Chris Date qui est l’inventeur de la formulation de la jointure qui a votre faveur continue à utiliser la forme « FROM A, B », c'est vous dire...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Attention, votre requête ne répond pas à la demande :
    Supposons que M. Albert soit l’auteur et l’illustrateur de l’ouvrage « Inner join et NULL pour les nuls » et qu’il soit aussi l’auteur de l’ouvrage « Tout sur la norme SQL ». Le résultat du comptage est en l’occurrence > 2, donc M. Albert ne figure pas dans le résultat. Qui plus est, si M. Bernard est l’auteur de « L’union de la carpe et du lapin » et l’illustrateur de « Qu’est-ce qu’Having ? » et n’a rien commis d’autre, alors il figure à tort dans le résultat...
    Mince, tout à fait exact
    Je voudrais sélectionner les ouvrages pour lesquels l'auteur est aussi le dessinateur.
    Citation Envoyé par fsmrel Voir le message
    Accessoirement, votre requête n’est pas emboîtée (SELECT mis entre parenthèses), donc selon la norme SQL 2003 elle n’est pas une sous-requête (subquery).
    je ne voulais pas surcharger, mais en effet la sous-requête devrait mises entre parenthèses pour avoir ce nom



    Citation Envoyé par fsmrel Voir le message
    La jointure proposée par mast3r est tout à fait respectable. Au point que, paradoxe ! Chris Date qui est l’inventeur de la formulation de la jointure qui a votre faveur continue à utiliser la forme « FROM A, B », c'est vous dire...
    et pourtant ce n'est pas la norme (que dit t'on déjà à propos des cordonnier ? )
    Merci d'ajouter un sur les tags qui vous ont aidé

  8. #8
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par dehorter olivier Voir le message
    et pourtant ce n'est pas la norme
    Selon la norme, la clause FROM doit respecter la syntaxe :
    FROM <Table reference> [, <Table reference> ...]
    Table reference peut notamment représenter un simple nom de table, ce qu’a fait mast3r : il n’a donc pas commis d’entorse à la norme. Ce qu’il a codé dans le FROM est un produit cartésien, ce qui est baptisé CROSS JOIN dans la norme.

    L’expression A CROSS JOIN B est sémantiquement identique à l’expression :
    SELECT *
    FROM A, B
    Je me réfère en cela à A Guide to THE SQL STANDARD Third Edition par C.J. Date et Hugh Darwen.

    N.B. Darwen n'est pas un mauvais cordonnier puisqu'il a longtemps représenté le Royaume-Uni au sein des comités qui font la norme SQL (et fait remettre aux calendes la prise en compte de propositions qu'il a démontré comme étant invalides donc dangereuses).
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Novembre 2012
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Bonsoir,

    Merci a vous deux pour vos réponses, ça m'a été très utile en effet, cependant je me pose une question, est ce qu'on peut faire une auto jointure 2 fois? en d'autres termes avoir 3 fois la table??

    car je voudrais par exemple afficher les livres qui sont en Anglais, Français et Espagnol.

    j'ai fait une petite requête qui à l'air de marcher, j'ai utilisé l'intersection.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT x.titre FROM ouvrage x where x.lid = (select lid from langue where lnom = 'Anglais') intersect
    SELECT y.titre FROM ouvrage y where y.lid = (select lid from langue where lnom = 'Espagnol') intersect
    SELECT z.titre FROM ouvrage z where z.lid = (select lid from langue where lnom = 'Grec') ;

    ça à l'air d'être correct, ça me ramène l'ouvrage qui est publié dans les 3 langues.

    qu'est ce que vous en dites? des petits modif' peut être, une requête plus opti?

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 814
    Points
    17 814
    Par défaut
    J'aurai écrit la première requête ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT ouv.ou_id, ouv.titre
      FROM ouvrage ouv
     WHERE EXISTS ( SELECT NULL
                      FROM a_ecrit aec 
                     WHERE aec.rôle in ('Auteur', 'Dessinateur')
                       AND aec.ou_id = ouv.ou_id
                  GROUP BY aec.aid
                    HAVING count(distinct aec.rôle) = 2);
    Quant au second besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      SELECT ouv.ou_id, ouv.titre
        FROM ouvrage ouv
        JOIN langue  lng
          ON lng.lid = ouv.lid
       WHERE lng.lnom in ('Anglais', 'Espagnol', 'Grec')
    GROUP BY ouv.ou_id, ouv.titre
      HAVING count(distinct lng.lid) = 3;

Discussions similaires

  1. Problème avec WHERE
    Par stephane432 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 15/06/2007, 18h18
  2. problème avec WHERE champ = NULL
    Par Tchupacabra dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/03/2007, 23h28
  3. Réponses: 5
    Dernier message: 10/07/2006, 13h05
  4. Problème avec le WHERE
    Par izou9002 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 12/01/2006, 16h03
  5. Problème avec UNION et WHERE
    Par portu dans le forum Langage SQL
    Réponses: 13
    Dernier message: 20/04/2005, 12h29

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