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 de comparaison ensembliste


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 7
    Points
    7
    Par défaut Problème de comparaison ensembliste
    Bonjour à tous,

    je rencontre des difficultés à écrire une requête, et après de nombreuses recherches sans trouver de solution sur internet, je viens vous soumettre le problème.

    Je dispose de deux tables (modélisant chacune une relation entre deux entités, i.e. du "manytomany"):
    - une table RELATION1 associant des codes à des compétences: un CODE renvoie vers 1..N COMPÉTENCES
    - une table RELATION2 associant des socles à des compétences: un SOCLE est composé de 1..N COMPÉTENCES

    Nom : capture.png
Affichages : 158
Taille : 9,3 Ko

    Ex de données RELATION1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    code1, competence1
    code1, competence2
    code1, competence3
    code2, competence1
    code2, competence3
    code2, competence4
    Ex de données RELATION2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    socle1, competence1
    socle1, competence2
    socle1, competence3
    socle1, competence4
    socle2, competence1
    socle2, competence2
    socle2, competence5
    Je cherche à déterminer, pour un SOCLE donné, la liste des CODES qui possèdent toutes les COMPETENCES du socle.

    Dans l'exemple ci-dessus:
    - pour "socle1" passé en paramètre, je souhaite "code1" et "code2" car les deux codes ont toutes leurs compétences faisant partie des compétences de "socle1"
    - pour "socle2" passé en paramètre, il n'y a aucun retour attendu car aucun code ne contient "competence5".

    J'espère être clair.

    Merci d'avance

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Ce problème doit pouvoir se résoudre par la division relationnelle...
    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
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    J'étais passé à côté, enfin un début de piste, merci

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour Slylord


    Dans le style de Chris Date, au début des années quatre-vingts. Pour ce qui concerne le socle socle1 :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select distinct id_code
    from relation1 as dividende
    where not exists
         (select id_socle, id_competence
          from (select distinct id_socle, id_competence from relation2 where id_socle = 'socle1') as diviseur 
          where not exists
               (select *
                from  relation1 as inter
                where inter.id_code = dividende.id_code
                and   inter.id_competence = diviseur.id_competence)) ;
    (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
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Quelques explications au sujet de la requête que j’ai proposée :


    Comme le suggère al1_24, la division relationnelle est faite pour résoudre votre problème, grâce à l’opérateur DIVIDEBY :

    (Relation1 DIVIDEBY (Relation2 WHERE id_socle = 'socle1')) {id_code}

    Ce qui se lit :

    Diviser Relation1 par la restriction de Relation2 à 'socle1', puis projeter le résultat sur id_code.

    SQL ne proposant pas cet opérateur, il faut donc le paraphraser en faisant des contorsions. Prenons donc l’énoncé :

    (1) « Quels sont les codes qui comportent toutes les références du socle 'socle1' »

    La quantification universelle permet de résoudre le problème. Mais, si SQL propose un avatar de la quantification existentielle avec EXISTS, ce langage ne propose rien quant à la quantification universelle. Heureusement, on sait exprimer la quantification universelle au moyen de la quantification existentielle :

    (∀x)Fx ≡ —(∃x)–Fx

    Du fait de la double négation, on paraphrase donc ainsi l’énoncé (1) :

    (2) « Quels sont les codes pour lesquels il n’existe pas de compétence qui n’existe pas pour le socle ' socle1' »

    D’où la traduction un peu tarabiscotée que j'avais faite en SQL.


    Il existe d’autres façons de s’en sortir (au moyen de la comparaison relationnelle par exemple, proposée par Date), mais celle que j’ai proposée remonte aux années soixante-dix, proposée par Date aux utilisateurs de SEQUEL (SQL), et qui s’appuie en l'occurrence sur la logique de Frege.
    (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.

  6. #6
    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 820
    Points
    17 820
    Par défaut
    J'aime bien la version agrégée de cette solution.
    Requêtes faites avec SQL-Server 2012 :
    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
    create table RELATION1
    ( code       varchar(8)
    , competence varchar(20)
    , constraint pk_relation1
        primary key (code, competence)
    );
     
    create table RELATION2
    ( socle      varchar(8)
    , competence varchar(20)
    , constraint pk_relation2
        primary key (socle, competence)
    );
     
    insert into RELATION1 values
    ('code1', 'competence1'),
    ('code1', 'competence2'),
    ('code1', 'competence3'),
    ('code1', 'competence4'),
    ('code2', 'competence1'),
    ('code2', 'competence3'),
    ('code2', 'competence4');
     
    insert into RELATION2 values
    ('socle1', 'competence1'),
    ('socle1', 'competence2'),
    ('socle1', 'competence3'),
    ('socle1', 'competence4'),
    ('socle2', 'competence1'),
    ('socle2', 'competence2'),
    ('socle2', 'competence5');
     
     
      select code
        from RELATION1
       where competence in (select competence from RELATION2 where socle = 'socle1')
    group by code
      having count(*) = (select count(*) from RELATION2 where socle = 'socle1');
     
    CODE
    -----
    code1
    @fsmrel, je pense qu'on peut légèrement simplifier votre requête.
    La présence d'une clef primaire dans RELATION2 permet de supprimer le DISTINCT de la ligne #5, et dès lors cette vue en ligne n'a plus de sens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT DISTINCT id_code
      FROM relation1 AS dividende
     WHERE NOT EXISTS (SELECT NULL
                         FROM relation2 AS diviseur 
                        WHERE diviseur.id_socle = 'socle1'
                          AND NOT EXISTS (SELECT NULL
                                            FROM relation1 AS inter
                                           WHERE inter.id_code       = dividende.id_code
                                             AND inter.id_competence = diviseur.id_competence));

  7. #7
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup pour votre aide Je vais vérifier et si ok, je tag résolu. Merci encore !

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/03/2006, 12h39
  2. Réponses: 11
    Dernier message: 22/03/2006, 21h57
  3. problème de comparaison table dans requète.
    Par Sendo dans le forum Access
    Réponses: 8
    Dernier message: 09/03/2006, 11h10
  4. Problème de comparaison (chez lycos)
    Par Tuscelan dans le forum Langage
    Réponses: 4
    Dernier message: 10/11/2005, 18h13
  5. Problème de comparaison de dates
    Par MiJack dans le forum Langage SQL
    Réponses: 2
    Dernier message: 12/03/2004, 21h43

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