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 :

Recherche d'un document en relation avec plusieurs motCle


Sujet :

Langage SQL

  1. #1
    J M
    J M est déconnecté
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 10
    Points : 12
    Points
    12
    Par défaut Recherche d'un document en relation avec plusieurs motCle
    Un précédent message ayant été déplacé sur le Forum Access, je reformule mon problème ici, car je pense qu'il s'agit réellement d'un problème SQL.

    MES 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
     
    CREATE TABLE Doc (
    idDoc bigint NOT NULL ,
    titreDoc nvarchar (50) NOT NULL ,
    CONSTRAINT PK_Doc PRIMARY KEY (idDoc)
    );
     
    CREATE TABLE DocMot (
    idDoc bigint NOT NULL ,
    idMot bigint NOT NULL ,
    CONSTRAINT PK_DocMot PRIMARY KEY (idDoc, idMot)
    );
     
    CREATE TABLE Mot (
    idMot bigint NOT NULL ,
    motCle nvarchar (50) NOT NULL ,
    CONSTRAINT PK_Mot PRIMARY KEY (idMot)
    );
    MES VALEURS
    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 Doc (idDoc, titreDoc) VALUES (1, 'titre1');
    INSERT INTO Doc (idDoc, titreDoc) VALUES (2, 'titre2');
    INSERT INTO Doc (idDoc, titreDoc) VALUES (3, 'titre3');
     
    INSERT INTO Mot (idMot, motCle) VALUES (1, 'mot1');
    INSERT INTO Mot (idMot, motCle) VALUES (2, 'mot2');
    INSERT INTO Mot (idMot, motCle) VALUES (3, 'mot3');
    INSERT INTO Mot (idMot, motCle) VALUES (4, 'autre mot1');
     
    INSERT INTO DocMot (idDoc, idMot) VALUES (1, 1);
    INSERT INTO DocMot (idDoc, idMot) VALUES (1, 2);
    INSERT INTO DocMot (idDoc, idMot) VALUES (1, 3);
     
    INSERT INTO DocMot (idDoc, idMot) VALUES (2, 1);
    INSERT INTO DocMot (idDoc, idMot) VALUES (2, 2);
    INSERT INTO DocMot (idDoc, idMot) VALUES (2, 3);
    INSERT INTO DocMot (idDoc, idMot) VALUES (2, 4);
     
    INSERT INTO DocMot (idDoc, idMot) VALUES (3, 1);
    INSERT INTO DocMot (idDoc, idMot) VALUES (3, 2);
    INSERT INTO DocMot (idDoc, idMot) VALUES (3, 4);
    MON PROBLEME
    Comment obtenir tous les titreDoc en relation avec :
    - un motCle contenant 'mot1'
    - ET un motCle contenant 'mot2'
    - ET un motCle contenant 'mot3'

    RESULTAT ATTENDU (on notera l'absence de titre3)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    titreDoc
    ---------
    titre1
    titre2
    MA REQUETE SQL (elle fonctionne)
    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 DISTINCT d.titreDoc
    FROM Doc d
      INNER JOIN DocMot dm1 ON d.idDoc = dm1.idDoc
      INNER JOIN Mot m1 ON dm1.idMot = m1.idMot
     
      INNER JOIN DocMot dm2 ON d.idDoc = dm2.idDoc
      INNER JOIN Mot m2 ON dm2.idMot = m2.idMot
     
      INNER JOIN DocMot dm3 ON d.idDoc = dm3.idDoc
      INNER JOIN Mot m3 ON dm3.idMot = m3.idMot
     
    WHERE (m1.motCle LIKE N'%mot1%')
      AND (m2.motCle LIKE N'%mot2%')
      AND (m3.motCle LIKE N'%mot3%')
    MA QUESTION
    Avec cette syntaxe, j'ai 2 INNER JOIN par motCle recherché, ce qui est coûteux.
    J'ai des problèmes de performances avec cette syntaxe à partir de 3 mots sous ACCESS 2000.
    Existe-t-il une syntaxe SQL moins coûteuse pour arriver au même résultat ?

    Merci

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 11
    Points : 11
    Points
    11
    Par défaut
    Voila une seule jointure, pour le résultat souhaité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT D.titreDoc
    FROM Doc AS D 
    INNER JOIN (Mot AS M INNER JOIN DocMot AS DM ON M.idMot = DM.idMot) ON D.idDoc = 
    WHERE m.mot LIKE '*mot1*' OR m.mot LIKE '*mot2*' OR m.mot LIKE '*mot3*'
    GROUP BY D.titreDoc
    HAVING SUM(InStr(m.mot, 'mot1')) <>0 
    AND SUM(InStr(m.mot, 'mot2')) <>0 
    AND SUM(InStr(m.mot, 'mot3')) <>0
    on sélectionne tous les titreDoc qui comportent au moins un des 3 mots ( mot1, mot2, mot3). Ensuite on groupe par titreDoc et on fait la somme des positions de chaque mot ( SUM(Instr(...)) ). On ne conserve que les groupements qui ont les trois sommes <>0 ( HAVING )

    Normalement ça marche sur access.

    d:->

  3. #3
    J M
    J M est déconnecté
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2002
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 10
    Points : 12
    Points
    12
    Par défaut
    Merci, ça marche.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/04/2014, 14h16
  2. Réponses: 8
    Dernier message: 31/01/2012, 19h02
  3. [VBA-E]rechercher avec plusieur critère.
    Par morgan47 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 08/06/2006, 19h48
  4. [hibernate] relation one-to-many avec plusieurs clés
    Par seb_fou dans le forum Hibernate
    Réponses: 6
    Dernier message: 16/03/2006, 14h47
  5. Réponses: 6
    Dernier message: 04/11/2005, 17h09

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