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 requête SQL avec jointure


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Problème requête SQL avec jointure
    Bonjour,
    Je n'arrive pas à faire une jointure, je vous explique mon problème :

    J'ai des tables :
    USER : table utilisateur
    MUSIC : contenant des chansons
    MUSICSTATUS : représentant des statuts de chansons (lien simple avec clé étrangère)
    COMMENT : table de commentaires associés à des musiques
    READCOMMENT : table contenant une entrée pour chaque commentaire lu par un utilisateur
    MUSICLIKE: une entrée par musique "likée" en fonction d'un utilisateur
    ------
    Je souhaite simplement récupérer une liste de chansons avec le nombre de commentaires non-lus ainsi que le nombre de likes associés.
    ------
    Première requête fonctionnelle comprenant le compte de commentaires non lus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT MUSIC.MUS_ID, MUS_TITLE, MUS_ARTIST, MUS_DATE, USER.USR_PSEUDO, USER.USR_ID, MUSICSTATUS.STAT_ID, (count(COMMENT.COM_ID) - count(READCOMMENT.COM_ID)) as MSG_UNREAD
    FROM MUSIC
    INNER JOIN USER ON USER.USR_ID = MUSIC.USR_ID
    INNER JOIN MUSICSTATUS ON MUSICSTATUS.STAT_ID = MUSIC.STAT_ID
    LEFT JOIN COMMENT ON MUSIC.MUS_ID = COMMENT.MUS_ID AND COMMENT.COM_DELETED = 0
    LEFT JOIN READCOMMENT ON MUSIC.MUS_ID = READCOMMENT.MUS_ID AND READCOMMENT.USR_ID = ?
    WHERE MUSIC.STAT_ID = ? AND MUS_DELETED = 0
    GROUP BY MUS_ID
    ORDER BY MUSIC.MUS_LASTUPDATE ASC, MUSIC.MUS_DATE
    -------
    Autre requête qui n'est pas fonctionnelle, où j'ai essayé d'intégrer le nombre de likes en plus ainsi que le fait d'avoir soi-même liké ou pas (quand le nombre de likes est à 0, le champ prend la valeur de mon nombre de commentaires non-lus) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT MUSIC.MUS_ID, MUS_TITLE, MUS_ARTIST, MUS_DATE, USER.USR_PSEUDO, USER.USR_ID, MUSICSTATUS.STAT_ID, (count(COMMENT.COM_ID) - count(READCOMMENT.COM_ID)) as MSG_UNREAD, count(ml1.ML_ID) as COUNT_MUSICLIKE, count(ml1.ML_ID) as I_LIKE
    FROM MUSIC
    INNER JOIN USER ON USER.USR_ID = MUSIC.USR_ID
    INNER JOIN MUSICSTATUS ON MUSICSTATUS.STAT_ID = MUSIC.STAT_ID
    LEFT JOIN COMMENT ON MUSIC.MUS_ID = COMMENT.MUS_ID AND COMMENT.COM_DELETED = 0
    LEFT JOIN READCOMMENT ON MUSIC.MUS_ID = READCOMMENT.MUS_ID AND READCOMMENT.USR_ID = ?
    LEFT JOIN MUSICLIKE ml1 ON MUSIC.MUS_ID = ml1.MUS_ID
    LEFT JOIN MUSICLIKE ml2 ON MUSIC.MUS_ID = ml2.MUS_ID AND ml2.USR_ID = ?
    WHERE MUSIC.STAT_ID = ? AND MUS_DELETED = 0
    GROUP BY MUS_ID
    ORDER BY MUSIC.MUS_LASTUPDATE ASC, MUSIC.MUS_DATE

    Pouvez-vous m'aider ? Merci !

  2. #2
    Membre averti
    Avatar de diablo-dz
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2014
    Messages : 75
    Points : 327
    Points
    327
    Par défaut
    Bonsoir
    Je vois que t'as oublié de mettre l’ensemble de tes tables que tu veux joindre !!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT MUSIC.MUS_ID, MUS_TITLE, MUS_ARTIST, MUS_DATE, USER.USR_PSEUDO, USER.USR_ID, MUSICSTATUS.STAT_ID, (count(COMMENT.COM_ID) - count(READCOMMENT.COM_ID)) AS MSG_UNREAD, count(ml1.ML_ID) AS COUNT_MUSICLIKE, count(ml1.ML_ID) AS I_LIKE
    FROM MUSIC,USER,MUSICSTATUS,COMMENT,READCOMMENT,.....
    INNER JOIN USER ON USER.USR_ID = MUSIC.USR_ID
    INNER JOIN MUSICSTATUS ON MUSICSTATUS.STAT_ID = MUSIC.STAT_ID
    LEFT JOIN COMMENT ON MUSIC.MUS_ID = COMMENT.MUS_ID AND COMMENT.COM_DELETED = 0
    LEFT JOIN READCOMMENT ON MUSIC.MUS_ID = READCOMMENT.MUS_ID AND READCOMMENT.USR_ID = ?
    LEFT JOIN MUSICLIKE ml1 ON MUSIC.MUS_ID = ml1.MUS_ID
    LEFT JOIN MUSICLIKE ml2 ON MUSIC.MUS_ID = ml2.MUS_ID AND ml2.USR_ID = ?
    WHERE MUSIC.STAT_ID = ? AND MUS_DELETED = 0
    GROUP BY MUS_ID
    ORDER BY MUSIC.MUS_LASTUPDATE ASC, MUSIC.MUS_DATE
    Essaye avec ça , et on en parlera.
    Je crois que tu as besoins d'une requête imbriquée, avec réserve !
    A++
    Si une réponse vous a permis d'avancer , n'oublie pas de mettre
    Ne pas oublier

  3. #3
    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 813
    Points
    30 813
    Par défaut
    A moins de vouloir créer un produit cartésien géant et faire exploser ton SGBD, la proposition de diablo-dz n'est certainement pas la bonne.
    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.

  4. #4
    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 018
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 018
    Points : 23 710
    Points
    23 710
    Par défaut
    Vous avez oublié de nous dire quel est votre SGBD.
    Allez, je prends les paris : MySQL ?
    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

  5. #5
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci de votre aide, la première solution n'a pas fonctionné.
    Effectivement je suis bien sur MySQL.

    Avez-vous une idée d'où peut bien venir l'erreur ?

  6. #6
    Membre averti
    Avatar de diablo-dz
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2014
    Messages : 75
    Points : 327
    Points
    327
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    A moins de vouloir créer un produit cartésien géant et faire exploser ton SGBD, la proposition de diablo-dz n'est certainement pas la bonne.
    J'ai proposé des requêtes imbriquées.
    Tu peux relire ce que j'ai répondu
    Si une réponse vous a permis d'avancer , n'oublie pas de mettre
    Ne pas oublier

  7. #7
    Membre averti
    Avatar de diablo-dz
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2014
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2014
    Messages : 75
    Points : 327
    Points
    327
    Par défaut un début de solution
    Bonsoir à vous
    Après réflexion, je me suis posé la question de savoir quoi faire à ta place ?
    Pour éviter le cas cité je te propose de créer une vue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE VIEW v AS SELECT MUSIC.MUS_ID, MUS_TITLE, MUS_ARTIST, MUS_DATE, USER.USR_PSEUDO, USER.USR_ID, MUSICSTATUS.STAT_ID
    FROM MUSIC
                     INNER JOIN USER ON USER.USR_ID = MUSIC.USR_ID
                             INNER JOIN MUSICSTATUS ON MUSICSTATUS.STAT_ID = MUSIC.STAT_ID
                                     LEFT JOIN COMMENT ON MUSIC.MUS_ID = COMMENT.MUS_ID AND COMMENT.COM_DELETED = 0
                                                LEFT JOIN READCOMMENT ON MUSIC.MUS_ID = READCOMMENT.MUS_ID AND READCOMMENT.USR_ID = ?
    Essaye de vérifier tes jointures car je ne peux pas les tester !
    Et là il te reste simplement à faire ta requête comme quoi tu as une seule table.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CREATE VIEW v AS SELECT c1,c2,c3  FROM t;
    SELECT *,COUNT(*) FROM v
     GROUP BY ....
    J’espère que ça va fonctionner
    J’attends la suite
    A++
    Si une réponse vous a permis d'avancer , n'oublie pas de mettre
    Ne pas oublier

  8. #8
    Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonjour,
    Je vois bien l’intérêt de créer une vue pour le principe mais ça ne résout pas mon problème de ma jointure.
    Si je fais une vue d'une jointure incorrecte, peu importe si j'appelle cette vue ou que je fasse la requête directement, ça ne marchera pas.

    Avez-vous une autre idée ?

    Merci de m'aider !

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Ce que vous obtenez est (à moitié) normal :
    Lorsque vous ajoutez vos jointures pour les Likes, vous multipliez les lignes pour chaque musique, en fonction du nombre de commentaires. Si vous avez 2 commentaires pour une musique, vous aurez donc 2 lignes (avant regroupement). Si vous avez 3 Likes pour cette même musique, cela fera 6 lignes en tout.
    Cela dit :
    quand le nombre de likes est à 0, le champ prend la valeur de mon nombre de commentaires non-lus
    Ceci ne devrait pas arriver, car quand vous spécifiez un nom de colonne dans une COUNT, les NULL ne sont pas comptés...
    Pour comprendre cela, la structure complète de vos tables, voire un petit jeu d'essai pourrait nous aider... à mieux vous aider !

    Je vois plusieurs solutions :
    1/ Faites des COUNT(DISTINCT LaColonneId) pour ne pas compter plusieurs fois le même Like, ou le même commentaire
    2/ Mettez le résultat de votre première requête (celle qui est fonctionnelle) en sous requête (pseudo table), et ajoutez vos jointures sur les tables des likes sur cette pseudo table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT ...
    FROM (
      -- [votre requete n°1 ici]
    ) UnAlias
    LEFT JOIN ... --(tables des likes)
    GROUP BY ...
    3/ certainement la moins élégante et la moins performante : faites des sous requêtes corrélées dans le select pour chaque COUNT distinctement.

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

Discussions similaires

  1. Problème requête sql avec plusieurs jointures
    Par CocoX02 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 19/02/2015, 13h33
  2. Requête sql avec jointure et table vide (ou tuple nulle)
    Par Aenur56 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 29/04/2010, 14h10
  3. Construction d'une requête SQL avec jointure
    Par Didiou35 dans le forum Requêtes
    Réponses: 3
    Dernier message: 08/10/2009, 22h26
  4. Requête SQL avec jointure
    Par manu32320 dans le forum Zend_Db
    Réponses: 3
    Dernier message: 17/05/2009, 00h19
  5. Requête SQL avec jointure sur trois tables
    Par pit2121 dans le forum SQL
    Réponses: 0
    Dernier message: 19/05/2008, 20h24

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