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 :

INNER JOIN, LEFT JOIN


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Mitaka
    Profil pro
    formaTRICE en informatique
    Inscrit en
    Avril 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : formaTRICE en informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 192
    Par défaut INNER JOIN, LEFT JOIN
    bonjour,
    je n'arrive pas à faire une requête assez complexe et j'ai vraiment besoin de vos lumières.
    En effet, j'ai une table produit et une autre historique :

    produit
    produit_id
    produit_date

    type
    prix
    historique
    produit_id
    produit_date
    produit_evenement_id
    produit_evenement_date

    etat
    Explications :
    Un produit est caractérisé par son id et sa date de création.
    Au cours de sa vie, il peut être modifié et/ou remplacé par un autre produit et l'on inscrit dans la table historique.

    on peut donc trouver les enregistrements suivants :

    - dans la table produit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    produit_id | produit_date | type | prix
       x00-001     2005-01-01    FR    10
       x00-002     2008-01-15    FR    10
       amd 200     2007-01-26    AMD    5
       amd 500     2009-02-01    AMD    5
       x020-200    2006-12-24    EN   10
    - dans la table historique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    produit_id | produit_date | produit_evt_id | produit_evt_date | etat
     x00-001    2005-01-01     amd 200            2007-01-26        modifié
     x00-001    2005-01-01     x00-002            2008-01-15        remplacé
     
     x00-002    2008-01-15     amd 500            2009-02-01        modifié
     
     x020-200    2006-12-24     amd 200            2007-01-26        modifié

    le produit x00-001 a été modifié par le produit amd 200 du 26-01-2007 puis remplacé par le produit x00-002 du 15-01-2008.
    le produit x00-002 a été modifié par le produit amd 500 du 01-02-2009 et le produit x020-200 a été modifié par le produit amd 200 di 26-01-2007.

    J'aimerai pouvoir récupérer tous les produits qui ont été seulement modifiés.
    Donc avec l'exemple ci dessus, les produits x00-002 et x020-200.

    Avez-vous une idée de la requête à construire ?

    Merci d'avance
    Désolée si je ne suis pas assez claire sur la problématique

  2. #2
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Saluton,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT h.produit_id
    FROM historique h
    INNER JOIN (SELECT h2.produit_id FROM historique h2 WHERE h2.etat='modifié') h3 
    ON  h.produit_id=h3.produit_id
    LEFT JOIN (SELECT h4.produit_id FROM historique h4 WHERE h4.etat='remplacé') h5 
    ON  h.produit_id=h5.produit_id
    WHERE h5.produit_id IS NULL
    Il y a peut-être plus optimisé, quoiqu'il n'y ait pas de corrélation, mais ça devrait le faire.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 183
    Par défaut
    bonjour,

    essaye ça:

    select produit_id
    from historique
    where etat='modifié'
    and produit_id not in (select produit_id from historique where etat ='remplacé')
    group by produit_id;

    c'est juste une idée pour que tu puisse avancer un peu, et améliorer la perfermance de ta requete par la suite.

  4. #4
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    En y réfléchissant il y a moyen de simplifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT h.produit_id
    FROM historique h
    LEFT JOIN (SELECT h2.produit_id FROM historique h2 WHERE h2.etat='remplacé') h3
    ON  h.produit_id=h3.produit_id
    WHERE h3.produit_id IS NULL
    AND h.etat='modifié'
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  5. #5
    Membre confirmé Avatar de Mitaka
    Profil pro
    formaTRICE en informatique
    Inscrit en
    Avril 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : formaTRICE en informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 192
    Par défaut
    ça y est ça marche ! youpi !
    par contre ça rame beaucoup :
    SELECT *
    FROM historique h
    INNER JOIN produit p ON p.produit_id=h.produit_id and p.produit_date = h.produit_date
    LEFT JOIN (SELECT * FROM historique h2 WHERE h2.etat ='R') h3
    ON h.produit_id=h3.produit_id and h.produit_date = h3.produite_date
    WHERE h3.produit_id IS NULL
    and h3.produit_date IS NULL
    AND h.etat='M'
    and p.type = 'FR'
    si vous avez une requête plus rapide à proposer, je la prend volontiers ^^

  6. #6
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    A toi de voir si la jointure doit aussi jouer sur la date.
    Peut être qu'en remplaçant la sous-requête par une jointure interne simple.
    Essayons
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT h.produit_id
    FROM historique h
    INNER JOIN produit p
    ON p.produit_id=h.produit_id
    LEFT JOIN historique h2 
    ON  h.produit_id=h2.produit_id AND h2.etat='remplacé'
    WHERE h3.produit_id IS NULL
    AND h.etat='modifié'
    AND p.type='FR'
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  7. #7
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    D'après moi ça ne sert à rien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    and h3.produit_date IS NULL
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  8. #8
    Membre confirmé Avatar de Mitaka
    Profil pro
    formaTRICE en informatique
    Inscrit en
    Avril 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : formaTRICE en informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 192
    Par défaut
    le problème c'est qu'il peut y avoir différents produits du même nom et de dates différentes donc je pense être obligée de faire les jointures.

  9. #9
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Citation Envoyé par hypothese Voir le message
    select produit_id
    from historique
    where etat='modifié'
    and produit_id not in (select produit_id from historique where etat ='remplacé')
    group by produit_id;
    Éventuellement SELECT DISTINCT, mais sûrement pas GROUP BY
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  10. #10
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 183
    Par défaut
    je ne suis pas un expert mysql, mais le group by n'aura aucun effet sur le résultat sauf une factorisation par produit_id et c'est ce qu'est demandé ( à savoir, connaitre les articles juste modifiés).

  11. #11
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Bonjour,

    Dans le cas présent, d'un point de vue résultats obtenus, GROUP BY ou DISTINCT, ça revient au même.
    En termes de performances, je ne sais pas .

    ced
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  12. #12
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Citation Envoyé par hypothese Voir le message
    le group by n'aura aucun effet sur le résultat sauf une factorisation par produit_id et c'est ce qu'est demandé ( à savoir, connaitre les articles juste modifiés).
    Pas de GROUP BY sans recours a une fonction statistique ou d'agrégation (MIN, MAX, AVG, SUM, COUNT, GROUP_CONCAT,...)
    L'unicité s'obtient avec DISTINCT, ce n'est pas la fonction de GROUP BY, même si MySQL l'autorise, par laxisme.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  13. #13
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Ah non, là, je ne suis pas d'accord avec toi. Et sur 2 points...
    D'abord, DISTINCT peut très bien s'appliquer aussi à des calculs d'agrégats :
    AVG(DISTINCT <expression>), SUM(DISTINCT <expression>),
    COUNT(DISTINCT <expression>), MAX(DISTINCT <expression>),
    MIN(DISTINCT <expression>)...
    Ensuite, ce n'est nullement un "laxisme" de la part de MySQL dans le cas présent (toutes les colonnes du SELECT sont bien dans le GROUP BY) et une telle requête fonctionnerait tout aussi bien sous SQL Server, Oracle et autre PostGresql... MySQL est "laxiste" sur un autre cas d'utilisation un peu particulier du GROUP BY (quand les colonnes dans la liste du SELECT qui ne font pas parties des fonctions d'agrégation ne sont pas toutes dans le GROUP BY).

    DISTINCT permet d'éliminer les doublons d'une réponse, GROUP BY groupe les lignes sélectionnées en se basant sur la valeur de colonnes spécifiées pour chaque ligne et renvoie une seule ligne par groupe. Dans le cas présent, c'est exactement la même chose .

    ced
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  14. #14
    Membre confirmé Avatar de Mitaka
    Profil pro
    formaTRICE en informatique
    Inscrit en
    Avril 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : formaTRICE en informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 192
    Par défaut
    merci les gens, je ne m'attendais pas à autant de réponse et en plus un débat de geeks :p

    Citation Envoyé par hypothese Voir le message
    bonjour,

    essaye ça:

    select produit_id
    from historique
    where etat='modifié'
    and produit_id not in (select produit_id from historique where etat ='remplacé')
    group by produit_id;

    c'est juste une idée pour que tu puisse avancer un peu, et améliorer la perfermance de ta requete par la suite.
    j'ai essayé cette requête mais elle ne renvoie rien du tout..

    SELECT h.produit_id
    FROM historique h
    LEFT JOIN (SELECT h2.produit_id FROM historique h2 WHERE h2.etat='remplacé') h3
    ON h.produit_id=h3.produit_id and h.produit_date = h3.produit_date
    WHERE h3.produit_id IS NULL
    AND h3.produit_date IS NULL
    AND h.etat='modifié'
    j'ai lancé cette requête et apparemment il me renvoie les produits remplacés

    Note : J'ai oublié de préciser que je voulais obtenir tous les produits seulement modifiés de type FR.

  15. #15
    Membre émérite Avatar de Hervé Saladin
    Homme Profil pro
    Ingénieur d'études en développement et déploiement d'applications
    Inscrit en
    Décembre 2004
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études en développement et déploiement d'applications
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2004
    Messages : 647
    Par défaut
    T'es sûre que t'as des données qui correspondent à ces critères dans ta base ?

  16. #16
    Membre confirmé Avatar de Mitaka
    Profil pro
    formaTRICE en informatique
    Inscrit en
    Avril 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : formaTRICE en informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 192
    Par défaut
    ben oui quand monsieur Hervé Saladin !
    autrement j'aurai une erreur tu crois pas ?

    (j'adore ton avatar, c'est très représentatif )

  17. #17
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Citation Envoyé par Mitaka Voir le message
    J'ai oublié de préciser que je voulais obtenir tous les produits seulement modifiés de type FR.
    Il te suffit d'ajouter un INNER JOIN produit p ON p.produit_id=h.produit_id
    et d'ajouter AND p.type='FR' à la clause WHERE
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  18. #18
    Membre émérite Avatar de Hervé Saladin
    Homme Profil pro
    Ingénieur d'études en développement et déploiement d'applications
    Inscrit en
    Décembre 2004
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études en développement et déploiement d'applications
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2004
    Messages : 647
    Par défaut
    Citation Envoyé par Mitaka
    ben oui [...]
    autrement j'aurai une erreur tu crois pas ?
    Ben non je crois pas !
    T'aurais précisément ce que tu obtiens : c'est à dire rien !
    Si la structure de ta base est bonne, mais que les données qui s'y trouvent ne contiennent pas d'enregistrement correspondant aux critères, alors ta requête renvoie 0 enregistrement, mais sans causer d'erreur.

  19. #19
    Membre confirmé Avatar de Mitaka
    Profil pro
    formaTRICE en informatique
    Inscrit en
    Avril 2003
    Messages
    192
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : formaTRICE en informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 192
    Par défaut
    j'avais pas compris ta question désolée

    non mais j'ai bien tout ce qu'il faut pour tester mes requêtes

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

Discussions similaires

  1. INNER et LEFT JOIN
    Par Beaudelicius dans le forum Langage SQL
    Réponses: 5
    Dernier message: 07/11/2011, 14h47
  2. left join , right join et inner join ?
    Par amine003 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 05/12/2008, 17h25
  3. Problème avec un LEFT JOIN/ RIGHT JOIN
    Par Moutonstar dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 25/11/2008, 14h03
  4. Jointures INNER JOIN LEFT JOIN
    Par tizla dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 31/05/2007, 12h12
  5. Fonction Left join, Right Join
    Par chandlerbing77 dans le forum Access
    Réponses: 2
    Dernier message: 22/06/2006, 16h36

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