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]Problème de jointure


Sujet :

Langage SQL

  1. #1
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut [SQL]Problème de jointure
    Bonjour à tous!

    Nous sommes nouveaux sur ce forum, et nous avons besoin de vous de toute urgence!

    Nous réalisons un projet en Java pour les cours et avons un petit souci avec une requête SQL.

    Voilà le problème:
    Nous avons une table contenant deux colonnes, l'une avec des identifiants de plats, l'autre avec des identifiants d'ingrédients.
    Nous souhaitons effectuer une requête sur cette table pour sélectionner les identifiants des plats qui contiennent tous les identifiants des ingrédients que l'on rentre dans la commande.

    En fait, l'utilisateur tape des noms d'ingrédients et nous voulons lui proposer les plats qui les contiennent tous (mais pas forcément que ceux ci). Donc on récupère les identifiants des ingrédients tapés, puis on veut effectuer une requete pour retourner les identifiants des plats correspondants.

    Pouvez-vous nous aider?

    Merci beaucoup à vous!

  2. #2
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    alors personne n'a une petite idée? si vous voulez des précisions n'hésitez pas à demander!!

  3. #3
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Citation Envoyé par rejul
    alors personne n'a une petite idée? si vous voulez des précisions n'hésitez pas à demander!!
    les ingredients entrés par l'utilisateur sont stockées dans une table ?

  4. #4
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    oui ils le sont

  5. #5
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Conformément aux règles du forum :

    - quelle base de données ?
    - Script des tables
    - Jeu d'essais.

    Ca permettra de t'aider beaucoup plus rapidement

  6. #6
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Nous travaillons avec netbeans et derby.

    Voici le code permettant de créer la table Ingrédient:

    String creationSQLPourDerby =
    "CREATE TABLE Ingredient (\n"+
    " idIng INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY, \n"+
    " nomIng VARCHAR(40) NOT NULL,\n"+
    " type INTEGER NOT NULL,\n"+
    " categorie INTEGER NOT NULL,\n"+
    " partie INTEGER,\n"+
    " CONSTRAINT PK_1 PRIMARY KEY(idIng)\n"+
    ")";
    st.executeUpdate(creationSQLPourDerby);


    code pour la création de la table Plat :

    String creationSQLPourDerby3 =
    "CREATE TABLE Plat (\n"+
    " idPlat INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY, \n"+
    " nomPlat VARCHAR(40) NOT NULL,\n"+
    " difficulte VARCHAR(20) NOT NULL,\n"+
    " note INTEGER,\n"+
    " tpsprepa INTEGER,\n"+
    " typeplat VARCHAR(20),\n"+
    " instru VARCHAR(5000),\n"+
    " commentaires VARCHAR(5000),\n"+
    " image BLOB(3000000),\n"+
    " CONSTRAINT PK_3 PRIMARY KEY(idPlat)\n"+
    ")";
    st.executeUpdate(creationSQLPourDerby3);

    code pour la création de la table joignant les tables Ingrédient et Plat

    String creationSQLPourDerby5 =
    "CREATE TABLE IngPlat (\n"+
    " idPlat INTEGER NOT NULL,\n"+
    " idIng INTEGER NOT NULL,\n"+
    " quantite FLOAT NOT NULL,\n"+
    " unite VARCHAR(20) NOT NULL,\n"+
    "CONSTRAINT FK_IngPlat_Ing FOREIGN KEY(idIng) REFERENCES Ingredient\n"+
    ")";
    st.executeUpdate(creationSQLPourDerby5);
    }


    Par contre, nous ne savons ce qu'est un jeu d'essai.
    Merci de votre aide.

  7. #7
    Membre confirmé
    Avatar de jpelaho
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Avril 2006
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 120
    Points : 487
    Points
    487
    Par défaut
    Je vous propose de créer une fonction dans votre langage ou une procédure stockée qui prend en paramètre l'identifiant de l'utilisateur et renvoie les plats qui lui conviennent selon les ingrédients qu'il a choisi.

    La table des ingrédients choisis par l'utilisateur est IngUser(UserId , idIng)
    Si @UserId est votre paramètre,



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT IdPlat,NomPlat FROM Plat P
    WHERE NOT EXISTS
    (
    SELECT idIng  FROM IngUser
    WHERE idIng  NOT IN 
        (SELECT idIng  FROM IngPlat WHERE IdPlat = P.IdPlat) AND UserId = @UserId
    )

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

    Supposons que l’on dispose d’une table CdeIngredient dans laquelle pour chaque commande, on trouve l’ensemble des ingrédients requis pour la commande.
    Soit PlatIngredient la table qui donne l’ensemble des ingrédients entrant dans la composition de chaque plat.
    Le schéma des tables est le suivant (clé primaire soulignée) :

    CdeIngredient (CdeId, IngredientId, ...)

    PlatIngredient (PlatId, IngredientId, ...)

    La théorie relationnelle propose l’opérateur DIVIDEBY pour obtenir tous les plats où l’on trouve (au moins) tous les ingrédients requis pour une commande donnée (disons 'c1'). L’ensemble de ces plats est le résultat de l’opération :

    (Plat DIVIDEBY Commande Where CdeId = 'c1') {PlatId}

    Malheureusement, SQL ne propose pas cet opérateur, il faut donc le paraphraser en faisant des contorsions.

    Prenons l’énoncé :

    « Quels sont les plats qui comportent tous les ingrédients de la commande 'c1' »

    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 :



    Du fait de la double négation, on paraphrase donc ainsi l’énoncé précédent :

    « Quels sont les plats pour lesquels il n’existe pas d’ingrédient qui n’existe pas dans la commande 'c1' »

    La requête SQL correspondante fait donc intervenir un double NOT EXISTS :
    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 Distinct PlatId
    From   PlatIngredient As P1
    Where  Not Exists (
           Select  *
           From    CdeIngredient As C
           Where   CdeId = 'c1'
           And     Not Exists (
                   Select  *
                   From    PlatIngredient As P2
                   Where   P1.PlatId = P2.PlatId
                     And   C.IngredientId = P2.IngredientId
                             )
                       ) ;
    Il existe d’autres façons de s’en sortir, mais celle-ci s’appuie uniquement sur la logique.

  9. #9
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Si les ingredients entrés par l'utilisateur sont stockés dans une table table1

    alors tu peux t'inspirer de ce genre de requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT idPlat FROM IngPlat 
    WHERE EXISTS (SELECT 1 FROM table1 WHERE IngPlat.IdIng = table1.idIng)
    GROUP BY IdPlat
    HAVING COUNT(1) >= (SELECT COUNT(1) FROM table1)
    bien entendu si table1 possede plusieurs utilisateurs, il faudra filtrer.
    Attention !! Requete non testée

    Bon courage

Discussions similaires

  1. [SQL] Problème de jointures
    Par howimboe dans le forum Langage SQL
    Réponses: 7
    Dernier message: 04/11/2010, 15h05
  2. [SQL] Problème avec jointure externe
    Par critok dans le forum Langage SQL
    Réponses: 4
    Dernier message: 29/10/2009, 12h49
  3. [SQL] problème de jointure
    Par vinz78 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 11/06/2007, 10h09
  4. [SQL]Problème avec jointure de tables
    Par benjisan dans le forum Requêtes et SQL.
    Réponses: 16
    Dernier message: 29/03/2007, 20h43
  5. [Requêtes SQL] Problème de jointure ?
    Par soso78 dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 18/12/2006, 15h37

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