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 :

SQL Requête difficile sur BDD


Sujet :

Langage SQL

  1. #1
    Membre du Club Avatar de rkade
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    48
    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 : Juillet 2011
    Messages : 48
    Points : 52
    Points
    52
    Par défaut SQL Requête difficile sur BDD
    Bonjour à tous,

    je dois réaliser des requêtes sur une base de données oracle express.

    Cependant, je sèche complètement sur une question.

    Voici ma base de données :

    DRAGONS :
    • dragon (représente le nom)
    • comportement_amoureux


    REPAS:
    • dragon_aimant (représente le nom du dragon qui aime)
    • dragon_aime (représente le nom du dragon qui est aimé)



    La requête doit retourner le nom des dragons timides ayant des relations avec tous les dragons macho. (Ayant des relations = est aimé ou aime)

    Bien évidemment nous voyons en relationnel qu'il s'agit d'une division. J'avais penser à du count( ) dans la requête mais je ne vois pas du tout comment m'y prendre.

    Je ne vous demande pas forcement de me donner la solution, mais des petites indications ?

    Merci à tous
    Exoskull vaincra

  2. #2
    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 : 60
    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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Indice qui devrait t'aider à construire ta requête :
    Citation Envoyé par rkade Voir le message
    La requête doit retourner le nom des dragons timides ayant des relations avec tous les dragons macho. (Ayant des relations = est aimé ou aime)
    Autrement dit :
    Les dragons timides dont le nombre de relations avec des dragons machos est égal au nombre de dragons machos.

    Il faut effectivement COUNT et GROUP BY ainsi que HAVING.

    Il y a des exemples dans le forum mais je ne saurais pas trop te dire sur quels critères les chercher. Peut-être avec ces trois mots du langage SQL que je viens de citer ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre du Club Avatar de rkade
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    48
    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 : Juillet 2011
    Messages : 48
    Points : 52
    Points
    52
    Par défaut
    Oui, j'étais parti sur les mêmes idées.

    Pour ce qui est du nombre de dragon macho, j'ai la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select count(*)
    from dragons
    where comportement_amoureux='macho'
    Mais pour la partie : "les dragons timides dont le nombre de relations avec des dragons macho" ... J'ai du mal.

    Ce que je souhaiterai, c'est savoir comment je peux lister les dragons avec qui les dragons timide ont des relations.

    Ensuite, je mets un group by dragon, et ensuite un having sur le count.

    j'avais pensé à 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
    SELECT d1.dragon, count(*) as nb_dragons_related
    FROM (dragons d1 JOIN aime ON d1.dragon=dragon_aimant) JOIN dragons d2 ON dragon_aime = d2.dragon
    WHERE d1.comportement_amoureux='timide' AND d2.comportement_amoureux='macho'
    GROUP BY d1.dragon
    UNION
    (
    SELECT d1.dragon, count(*) as nb_dragons_related
    FROM (dragons d1 JOIN aime ON d1.dragon=dragon_aimant) JOIN dragons d2 ON dragon_aime = d2.dragon
    WHERE d1.comportement_amoureux='macho' AND d2.comportement_amoureux='timide'
    GROUP BY d1.dragon
    )
    mais malheureusement, ce n'est pas ça

    EDIT : En fait j'ai peut-être trouvé la bonne 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
    select *
    from
    (
    SELECT d1.dragon, count(*) as nb_dragons_related
    FROM (dragons d1 JOIN aime ON d1.dragon=dragon_aimant) JOIN dragons d2 ON dragon_aime = d2.dragon
    WHERE d1.comportement_amoureux='timide' AND d2.comportement_amoureux='macho'
    GROUP BY d1.dragon
    UNION
    (
    SELECT d1.dragon, count(*) as nb_dragons_related
    FROM (dragons d1 JOIN aime ON d1.dragon=dragon_aimant) JOIN dragons d2 ON dragon_aime = d2.dragon
    WHERE d1.comportement_amoureux='macho' AND d2.comportement_amoureux='timide'
    GROUP BY d1.dragon
    )
    )
    where nb_dragons_related = (select count(*) from dragons where comportement_amoureux='macho')
    Dites moi ce que vous en pensez ? Si elle vous paraît exacte ?
    Exoskull vaincra

  4. #4
    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 : 60
    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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Reprenons ce que j'ai dit tout à l'heure :
    Les dragons timides dont le nombre de relations avec des dragons machos est égal au nombre de dragons machos.
    1) Les dragons timides qui aiment des dragons machos :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT d.dragon
    FROM DRAGONS d
    INNER JOIN aime a ON a.dragon_aimant = d.dragon
        INNER JOIN dragon d1 ON d1.dragon = a.dragon_aime
    WHERE d.comportement_amoureux = 'timide'
        AND d1.comportement_amoureux = 'macho'
    2) On ajoute à la première requête les dragons timides qui sont aimés des dragons machos :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT d.dragon AS dragon_timide, 
        d1.dragon AS autre_dragon
    FROM DRAGONS d
    INNER JOIN aime a ON a.dragon_aimant = d.dragon
        INNER JOIN dragon d1 ON d1.dragon = a.dragon_aime
    WHERE d.comportement_amoureux = 'timide'
        AND d1.comportement_amoureux = 'macho'
    UNION
    SELECT d.dragon, d1.dragon
    FROM DRAGONS d
    INNER JOIN aime a ON a.dragon_aime = d.dragon
        INNER JOIN dragon d1 ON d1.dragon = a.dragon_aimant
    WHERE d.comportement_amoureux = 'timide'
        AND d1.comportement_amoureux = 'macho'
    Note : Si une relation est réciproque (timide X aime macho Y et timide X est aimé de macho Y), UNION ne donnera qu'une fois le couple.

    3) On ne retient que les dragons timides qui ont autant de relations que le nombre de dragons machos :
    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
    SELECT tmp.dragon_timide
    FROM
    (
        SELECT d.dragon AS dragon_timide, 
            d1.dragon AS autre_dragon
        FROM DRAGONS d
        INNER JOIN aime a ON a.dragon_aimant = d.dragon
            INNER JOIN dragon d1 ON d1.dragon = a.dragon_aime
        WHERE d.comportement_amoureux = 'timide'
            AND d1.comportement_amoureux = 'macho'
        UNION
        SELECT d.dragon, d1.dragon
        FROM DRAGONS d
        INNER JOIN aime a ON a.dragon_aime = d.dragon
            INNER JOIN dragon d1 ON d1.dragon = a.dragon_aimant
        WHERE d.comportement_amoureux = 'timide'
            AND d1.comportement_amoureux = 'macho'
    ) tmp
    GROUP BY tmp.dragon_timide
    HAVING COUNT(*) = (
        SELECT COUNT(*)
        FROM DRAGONS
        WHERE comportement_amoureux = 'macho'
    )
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    La requête UNION ne serait pas un peu lourdingue par rapport au besoin?
    Il paraitrait plus naturel et plus simple de faire un OR dans la condition de jointure (aimant OR aimé).

  6. #6
    Membre du Club Avatar de rkade
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    48
    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 : Juillet 2011
    Messages : 48
    Points : 52
    Points
    52
    Par défaut
    Merci beaucoup à toi CinePhil ! Tes explications sont très clairs.

    Pour enlever l'union, et le remplacer par une condition OR. Je ne vois pas comment faire, j'ai réfléchis un peu sans trouver de réponse.
    Exoskull vaincra

  7. #7
    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 : 60
    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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    J'avais pensé le faire sans UNION au début mais comme c'est une condition double et sur deux instances de la table dragons, je n'ai pas trouvé comment faire (sans chercher des heures non plus).
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Avec le OR, je voyais une condition de ce style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT distinct d.dragon as timide
    FROM DRAGONS d
    INNER JOIN aime a ON (a.dragon_aime = d.dragon OR a.dragon_aimant=d.dragon)
    INNER JOIN dragons d1 ON (d1.dragon = a.dragon_aimant OR d1.dragon = a.dragon_aime)
    WHERE d.comportement_amoureux = 'timide'
     AND d1.comportement_amoureux = 'macho';

  9. #9
    Membre du Club Avatar de rkade
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    48
    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 : Juillet 2011
    Messages : 48
    Points : 52
    Points
    52
    Par défaut
    Je ne comprends pas la requête.

    Car la jointure va se faire de quelle manière ? Comment le OR dans le inner join va fonctionner ?
    Exoskull vaincra

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Conceptuellement, le "OU" vient de l'énoncé qui dit que "être en relation c'est est aimé ou aime", c.a.d que le 1er dragon doit être dans la colonne dragon_aimant ou dans la colonne dragon_aime, sachant que l'autre dragon doit figurer dans l'autre colonne.

    Le souci avec cette formulation vient peut-être du fait que tu n'as pratiqué jusqu'ici que du JOIN ou le ON serait limité à une équijointure (c.a.d une colonne de la table de gauche=une autre colonne de la table droite), mais en réalité on peut mettre n'importe quelle condition dans la clause ON. Quand la condition est vraie, l'exécuteur garde les lignes et quand elle est fausse il les élimine, peu importe la complexité de la condition.

  11. #11
    Membre du Club Avatar de rkade
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    48
    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 : Juillet 2011
    Messages : 48
    Points : 52
    Points
    52
    Par défaut
    En fait on a vu les jointures avec des conditions mais que en relationnel. En SQL, tu as raison, c'est la première fois que je vois ça.

    Merci, c'est vrai que ta requête est beaucoup plus courte, et je la trouve très compréhensible maintenant.

    Bonne journée à tous
    Exoskull vaincra

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

Discussions similaires

  1. Requête unique sur BdD multiples
    Par magohamoth dans le forum SQLite
    Réponses: 3
    Dernier message: 27/07/2011, 08h55
  2. [C++B5]Problème avec une requëte SQL sur BDD ACCESS
    Par Sleeping Lionheart dans le forum C++Builder
    Réponses: 7
    Dernier message: 22/04/2008, 09h03
  3. [SQL] requête croisée sur 2 tables
    Par franckydeluka dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 07/01/2008, 11h48
  4. [SQL] Requête complexe sur plusieurs tables
    Par BFH dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 21/09/2007, 16h21
  5. Requête SQL avec paramètre sur BDD Access
    Par BigMike dans le forum Windows Forms
    Réponses: 3
    Dernier message: 07/06/2007, 12h21

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