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

Requêtes MySQL Discussion :

Requête sur plusieurs tables avec plusieurs WHERE


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut Requête sur plusieurs tables avec plusieurs WHERE
    Bonjour à tous,

    Je suis un peu emmêlé dans ma requête et aimerais un oeil extérieur.

    Pour résumer, j'aimerais afficher dans une liste le produit de ma requête.

    J'ai plusieurs tables :
    theme (themes auxquels mon article peut correspondre)
    tarif_theme (relation entre mes articles et les les themes)
    tarif (liste de mes articles)
    prestation_tarif_fournisseur (liste de mes paniers, avec un ou plusieurs articles à chaque fois)


    Je pars du principe que dans mon panier, j'ai au moins un article.

    Le but est de sélectionner le ou les articles qui correspondent aux thèmes du ou des articles de mon panier.


    J'ai fait plusieurs tests, dont celui-ci, mais rien de marche :

    $val est l'id. de mon panier

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select * FROM tarif_theme, theme, prestation_tarif_fournisseur, tarif WHERE
    tarif_theme.idt_tarif=prestation_tarif_fournisseur.idt_tarif
    AND tarif_theme .idt_theme=theme.idt_theme
    AND prestation_tarif_fournisseur.idt_prst=$val";

    Si quelqu'un peut m'aiguiller, ce serait sympa...

    Merci !

  2. #2
    Membre confirmé
    Homme Profil pro
    Déveleoppeur Web/Mobile
    Inscrit en
    Avril 2013
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Déveleoppeur Web/Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 330
    Points : 545
    Points
    545
    Par défaut
    Bonjour,

    Il semblerait que actuellement ta requête soit juste destinée à récupérer les articles du panier.
    Tu peux procéder avec une requête imbriquée : ta première requête indique que tu sélectionne tous les articles pour lesquels le thème fait partie de la liste des thèmes provenant de ta sous-requête . Soit quelque chose comme :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * FROM tarif 
    WHERE tarif.idt_theme IN 
         (SELECT tarif_theme.idt_theme FROM tarif_theme, prestation_tarif_fournisseur
          WHERE tarif_theme.idt_tarif=prestation_tarif_fournisseur.idt_tarif
          AND prestation_tarif_fournisseur.idt_prst=$val)

    si tu as du mal à comprendre il faut te documenter à propos des requêtes imbriquées

  3. #3
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Est-ce la requête que tu as testée ainsi? Si oui, les espaces te poseront problème dans un premier temps..

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    AND tarif_theme .idt_theme=theme.idt_theme
    Pensez à regarder nos cours et tutoriels PHP ainsi que notre FAQ PHP avant de poser votre question!
    Un message vous a aidé, n'oubliez pas le

  4. #4
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    -Rpass-
    Merci pour cette réponse rapide, je ne suis pas expert en requête imbriquées en effet...
    Je vais essayer de poursuivre dans cette voie.

    Kreepz
    Non, pas de souci d'espace dans mon code, merci pour ta vigilance

  5. #5
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Bon, ca ne marche pas.

    Je n'ai pas de colonne idt_theme dans la table tarif, comme indiqué dans le premier Where.
    Pour cela il faudrait que je peux passe par table de relation tarif_theme faisant le lien entre tarif et theme (jespère etre clair).

    D'après ce que j'ai vu, ce where ne design qu'un nom de colonne, rien de plus.
    Il manquerait donc un autre where, ou une autre imbrication ? Est-ce possible ?

    Merci...

  6. #6
    Membre confirmé
    Homme Profil pro
    Déveleoppeur Web/Mobile
    Inscrit en
    Avril 2013
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Déveleoppeur Web/Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 330
    Points : 545
    Points
    545
    Par défaut
    Je ne connais pas la structure de ta table tarif ni le nom des colonnes, il faut adapter ma requête mais effectivement il manquait le lien entre tarif et theme

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select * FROM tarif, tarif_theme
    WHERE tarif.idt_tarif = tarif_theme.idt_tarif
    AND tarif_theme.idt_theme IN 
         (SELECT tarif_theme.idt_theme FROM tarif_theme, prestation_tarif_fournisseur
          WHERE tarif_theme.idt_tarif=prestation_tarif_fournisseur.idt_tarif
          AND prestation_tarif_fournisseur.idt_prst=$val)

  7. #7
    Membre émérite
    Homme Profil pro
    tripatouilleur de code pour améliorer mon quotidien boulistique
    Inscrit en
    Février 2008
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : tripatouilleur de code pour améliorer mon quotidien boulistique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2008
    Messages : 939
    Points : 2 287
    Points
    2 287
    Par défaut
    Bonjour à tous

    Je n'ai pas lu toutes les réponses car déjà quand je vois
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select * FROM tarif_theme, theme, prestation_tarif_fournisseur, tarif WHERE
    tarif_theme.idt_tarif=prestation_tarif_fournisseur.idt_tarif
    AND tarif_theme .idt_theme=theme.idt_theme
    AND prestation_tarif_fournisseur.idt_prst=$val";
    j'ai le poil qui se hérisse.
    Les experts vous diront que les jointures ne se font plus ainsi depuis près de 20 ans.

    Avant d'aller plus loin, je vous suggère de lire le tutoriel Les jointures, ou comment interroger plusieurs tables , afin de réaliser de belles et bonnes requêtes, dans lesquelles on distingue bien les jointures (Inner join/ left join / right join ... on) et la clause where.

    Pierre

  8. #8
    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
    1) Les jointures s'écrivent depuis plus de 20 ans avec l'opérateur JOIN ; il serait temps de s'y mettre !

    2) Il vaut mieux éviter la guerre des étoiles !

    3) Un code indenté et aéré est plus agréable à lire et à déboguer.

    4) L'utilisation d'alias pour les tables est fortement recommandé dès qu'il y a plus d'une table dans la requête. Cela facilite l'écriture et la lecture de celle-ci. Il faut ensuite utiliser systématiquement ces alias devant chaque colonne nommée pour savoir facilement de quelle table elle vient.

    5) Attention aux injections SQL ! Ne mettez pas votre variable $var directement dans la requête mais utilisez des requêtes paramétrées et vérifiez le type de la variable.

    Passons à votre problème...

    A) Quels sont les thèmes des articles présents dans le panier ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT tt.idt_theme
    FROM prestation_tarif_fournisseur p
    INNER JOIN tarif_theme tt ON tt.idt_tarif = p.idt_tarif
    WHERE p.idt_prst = :val
    B) Quels sont tous les articles correspondant à ces thèmes et qui ne sont pas dans le panier ?
    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 ta.idt_tarif -- + les autres colonnes souhaitées mais pas étoile !
    FROM tarif ta
    INNER JOIN tarif_theme tt1 ON tt1.idt_tarif = ta.idt_tarif
    	INNER JOIN 
    	(
    		SELECT tt.idt_theme
    		FROM prestation_tarif_fournisseur p
    		INNER JOIN tarif_theme tt ON tt.idt_tarif = p.idt_tarif
    		WHERE p.idt_prst = :val
    	) tmp ON tmp.idt_theme = tt1.idt_theme
    WHERE ta.idt_tarif NOT IN
    (
    	SELECT idt_tarif
    	FROM prestation_tarif_fournisseur
    	WHERE idt_prst = :val
    )
    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 !

  9. #9
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Merci pour le message.
    Désolé pour votre poil, vous avez entièrement raison, et j'ai presque honte.
    Mes bases de sql date effectivement de 1996

    Je me suis plongé depuis hier dans les jointures...

  10. #10
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Bonjour CinePhil,

    Tout d'abord, merci d'avoir pris le temps de répondre en détail à mon problème.

    Je suis ok sur les 5 points que vous évoquez.


    Voici un peu plus de détail sur la structure de mes tables, car je ne suis pas sûr d'avoir été assez clair.

    A/ table theme : liste des thèmes de mes différents articles
    champs : idt_theme, libelle_theme, etc.

    B/ table tarif : liste de mes articles
    champs : idt_tarif, libelle_tarif, prix_tarif, etc.

    C/ table prst : données générales du panier
    champs : idt_prst, date_prst, etc.

    D/ table prestation_tarif_fournisseur : liste des données spécifiques à chaque article de mon panier
    champs : idt_prst, idt_tarif, idt_fournisseur, etc.

    E/ table relation tarif_theme : relation entre mes articles et les themes possibles
    champs : idt_tarif et idt_theme

    Concernant le code que vous avez indiqué, pourquoi avoir écrit deux requêtes différentes ? Est-ce par simplicité, par logique ou par obligation ?

  11. #11
    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
    Concernant le code que vous avez indiqué, pourquoi avoir écrit deux requêtes différentes ? Est-ce par simplicité, par logique ou par obligation ?
    C'était pour vous expliquer la démarche de construction de la requête finale. Vous voyez que la première requête est la sous-requête en jointure dans la seconde.

    Répond-elle à votre besoin ?
    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 !

  12. #12
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Au temps pour moi, je ne sais pas lire !... ou trop rapidement.
    Je suis en train de la tester.

    Il y a encore quelques points obscurs comme le "tmp".
    Est-ce parce qu'on insère un SELECT intermédiaire ?

  13. #13
    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
    Quand vous mettez une sous-requête en jointure, il faut lui donner un alias pour que la condition de jointure et l'éventuelle présence de colonnes issues de la sous-requête dans le SELECT puisse s'opérer.

    Si un jour vous êtes confronté à un message d'erreur du genre "Every derived table must have its own alias", c'est qu'il manque un alias à une sous-requête.
    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 !

  14. #14
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Ok je comprends bien.

    En tout cas, un grand merci pour votre aide, la requête marche parfaitement !!
    J'avoue que je n'y serais pas arrivé seul.
    Ne me reste plus qu'à améliorer cela avec un order adéquat.

    J'ai au moins appris quelque chose et ai pas mal de requêtes à retravailler...

    Excellente journée

  15. #15
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    Je repasse ce post en non résolu car il reste un petit problème en suspens.

    Tout est quasiment bon, la requête ramène les bons articles.
    Mais, j'ai parfois deux ou trois fois le même.
    Cela est dû au fait qu'un article peut se trouver dans plusieurs thèmes différents.

    Comment intégrer dans cette requête le fait que je ne veux avoir qu'une fois au plus chaque article ?

    Merci d'avance.

  16. #16
    Modérateur
    Avatar de Kreepz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2011
    Messages : 681
    Points : 1 458
    Points
    1 458
    Billets dans le blog
    1
    Par défaut
    As-tu essayé avec un DISTINCT ?
    Pensez à regarder nos cours et tutoriels PHP ainsi que notre FAQ PHP avant de poser votre question!
    Un message vous a aidé, n'oubliez pas le

  17. #17
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    J'avais un doute, mais c'était juste le DISTINCT en effet.
    Merci pour cette réponse rapide.
    Je repasse en résolu !...

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

Discussions similaires

  1. [Requête SQL] - Select count avec plusieurs tables
    Par Pithonnette dans le forum SQL
    Réponses: 7
    Dernier message: 25/06/2009, 19h19
  2. Requetes sur deux tables avec plusieurs retour
    Par IP-Fix dans le forum Requêtes
    Réponses: 16
    Dernier message: 13/11/2008, 18h46
  3. Réponses: 4
    Dernier message: 05/03/2008, 09h32
  4. problème sur requête sur 3 tables avec une somme
    Par tomguiss dans le forum Requêtes
    Réponses: 4
    Dernier message: 27/12/2007, 16h44
  5. faire une seule table avec plusieurs table
    Par bossboss dans le forum Access
    Réponses: 4
    Dernier message: 08/01/2007, 16h11

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