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 :

Jointure SQL et doublons


Sujet :

Langage SQL

  1. #1
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut Jointure SQL et doublons
    Salut à tous.
    Je me retrouve face un problème que je n'arrive pas à régler.
    J'ai essayé différentes manière de faire mais je n'arrive jamais au résultat souhaité..

    Donc, je développe pour petit projet, un petit forum.
    Ce que je souhaite c'est, que sur l'index du forum juste le liste les différentes catégories du forum (annonce, aide, etc..) d'un coté et de l'autre afficher le dernier topic posté (auteur, date et titre).

    Donc j'ai trois table :
    categorie //Catégorie des forum
    topic // topic
    membres // table user du site
    et une table commentaire (mais je ne m'en sert pas, c'est juste les réponses aux topics).

    Ma requete (en l'état actuel)
    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 categorie.id AS catid, 
    categorie.titre, 
    categorie.description, 
    categorie.position, 
    membres.id AS iduser, 
    membres.pseudo, 
    topic.id AS topic_id, 
    topic.titre AS topic_titre, 
    topic.date AS date_topic,
     topic.categorie_id AS topic_cat_id
    FROM  `categorie` 
    LEFT JOIN topic ON topic.categorie_id = categorie.id
    LEFT JOIN membres ON membres.id = topic.membre_id
    ORDER BY date_topic DESC
    Et j'obtiens donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    catid	titre	description	position	iduser	pseudo	topic_id	topic_titre	date_topic	topic_cat_id
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	4	TEST req2	2015-08-02 18:23:58	3
    1	Ficolab	Annonces importantes	1	2	test	1	test date	2015-08-02 18:20:03	1
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	3	TEST req	2015-08-02 17:57:58	3
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	2	test	2	test	2015-07-28 17:47:11	3
    4	Suggestion	Une idées pour améliorer notre plateforme ?	4	NULL	NULL	NULL	NULL	NULL	NULL
    2	Vos projets	Discutions autour de vos projets	2	NULL	NULL	NULL	NULL	NULL	NULL
    On peux donc voir que j'ai ces ligne en trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	3	TEST req	2015-08-02 17:57:58	3
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	2	test	2	test	2015-07-28 17:47:11	3
    Chose que je souhaiterai bien éviter..
    Comment faire ?
    Une autre choses si je peux d'un cote trier par "position" (ordre de mes forum), et avoir bien dans la suite le dernier topic crée c'est le top.
    Merci à vous.

  2. #2
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Utilisez last/first dans leur version agrégée. Cherchez des exemples sur ce forum.

  3. #3
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    Salut,
    Après quelques recherche, j'ai pu trouvé des cas similaire au mien, mais je sèche également...

    De ce que j'ai compris, je dois faire dans ma jointure une requête imbriquée avec laquelle je sélectionne les dernières dates pour chaque catégories ?

  4. #4
    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,

    il existes différentes possibilité pour répondre au problème. En fonction du SGBDR, certaines ne seront toutefois pas possibles. Quel est le votre ?

  5. #5
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    Bonjour,
    Je suis sous MySQL et php, je bosse avec codeigniter

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 134
    Points : 38 557
    Points
    38 557
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par demenvil Voir le message
    On peux donc voir que j'ai ces ligne en trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	3	TEST req	2015-08-02 17:57:58	3
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	2	test	2	test	2015-07-28 17:47:11	3
    Une autre choses si je peux d'un cote trier par "position" (ordre de mes forum), et avoir bien dans la suite le dernier topic crée c'est le top.
    Merci à vous.
    Bonjour,

    Quand vous dites que vous avez ces lignes en trop, je suppose que vous voulez dire que vous n'en voulez qu'une des deux? sinon je n'ai pas compris pourquoi vous ne les voulez pas ni l'une ni l'autre.
    Pour n'afficher que les catégories distinctes (ce que je suppose donc) utilisez le mot clef "DISTINCT"
    Pour n'afficher que le dernier topic d'une catégorie, faites effectivement un sub-select avec le max(date), attention aux doublons, plusieurs topics peuvent avoir été postés au même moment (même un timestamp ne garantit pas à 100% l'unicité, même si les doublons sont rares)

    Ce qui pourrait donner :
    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
    SELECT  categorie.id AS catid, 
            categorie.titre, 
            categorie.description, 
            categorie.position, 
            membres.id AS iduser, 
            membres.pseudo, 
            topic.id AS topic_id, 
            topic.titre AS topic_titre, 
            topic.date AS date_topic,
            topic.categorie_id AS topic_cat_id
    FROM  `categorie` 
    LEFT JOIN topic 
      ON topic.categorie_id = categorie.id
    LEFT JOIN membres 
      ON membres.id = topic.membre_id
    where topic.horodatage = coalesce(
         (select distinct max(horodatage) from topic as subq
          where subq.categorie_id = topic.categorie_id), '')
    ORDER BY positionforum

  7. #7
    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
    Citation Envoyé par demenvil Voir le message
    Je suis sous MySQL
    ça va donc en effet limiter les possibilités.

    Vous pouvez en effet chercher les dernières dates pour chaque topic, en fait une jointure sur le résultat afin d'éliminer les plus anciens.

    Une autre approche : le dernier étant celui pour lequel il n'existe pas de plus récent, vous pouvez faire une sous requête corrélée dans un NOT EXISTS pour vérifier cette condition.

  8. #8
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Bonjour,

    Quand vous dites que vous avez ces lignes en trop, je suppose que vous voulez dire que vous n'en voulez qu'une des deux? sinon je n'ai pas compris pourquoi vous ne les voulez pas ni l'une ni l'autre.
    Pour n'afficher que les catégories distinctes (ce que je suppose donc) utilisez le mot clef "DISTINCT"
    Pour n'afficher que le dernier topic d'une catégorie, faites effectivement un sub-select avec le max(date), attention aux doublons, plusieurs topics peuvent avoir été postés au même moment (même un timestamp ne garantit pas à 100% l'unicité, même si les doublons sont rares)
    Non c'est juste que celle ci je ne les souhaite pas dans le retour de la requête.
    Pour la catégorie "Aide Ficolab" je souhaite le derniers topics, (et de même pour chaque catégories, la ma requête actuelle me sort tous les topics de chaque catégories je ne souhaite récupérer uniquement le dernier (ou pas la date ou par l'id).


    Le distinct j'ai essayé ne change rien.

  9. #9
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 134
    Points : 38 557
    Points
    38 557
    Billets dans le blog
    9
    Par défaut
    J'ai édité mon message précédent pour ajouter une requete, qui doit répondre à votre problème de sélection du post le plus récent (nos messages se sont croisés)

    Par contre, pouvez vous indiquer quelles sont les règles de gestion qui permettent d'identifier que ces 2 lignes ne sont pas à sélectionner ?

  10. #10
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    J'ai mis à jours votre requête pour qu'elle fonctionne.
    Le résultat n'est pas celui que je souhaite (mais 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
     
    SELECT categorie.id AS catid, categorie.titre, categorie.description, categorie.position, membres.id AS iduser, membres.pseudo, topic.id AS topic_id, topic.titre AS topic_titre, topic.date AS date_topic, topic.categorie_id AS topic_cat_id
    FROM  `categorie` 
    LEFT JOIN topic ON topic.categorie_id = categorie.id
    LEFT JOIN membres ON membres.id = topic.membre_id
    WHERE topic.date = COALESCE( (
     
    SELECT DISTINCT MAX( topic.date ) 
    FROM topic AS subq
    WHERE subq.categorie_id = topic.categorie_id ) ,  ''
    )
    ORDER BY  `categorie`.`position` ASC 
    LIMIT 0 , 30
    Et j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    catid	titre	description	position Croissant	iduser	pseudo	topic_id	topic_titre	date_topic	topic_cat_id
    1	Ficolab	Annonces importantes	1	2	test	1	test date	2015-08-02 18:20:03	1
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	3	TEST req	2015-08-02 17:57:58	3
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	4	TEST req2	2015-08-02 18:23:58	3
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	2	test	2	test	2015-07-28 17:47:11	3
    Le résultat que je souhaite serait plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    catid	titre	description	position	iduser	pseudo	topic_id	topic_titre	date_topic	topic_cat_id
    1	Ficolab	Annonces importantes	1	2	test	1	test date	2015-08-02 18:20:03	1
    2	Vos projets	Discutions autour de vos projets	2	NULL	NULL	NULL	NULL	NULL	NULL
    3	Aide Ficolab	Une question ? Besoin d'aide ?	3	3	kakao	4	TEST req2	2015-08-02 18:23:58	3
    4	Suggestion	Une idées pour améliorer notre plateforme ?	4	NULL	NULL	NULL	NULL	NULL	NULL
    Pour chaque catégorie, j'ai une quantité N de topics.
    Je souhaite juste récupérer le dernier topic créé par catégorie.
    Actuellement dans ma base pour les test pour la catégorie id= 3 (Aide Ficolab). j'ai 3 topics existant donc le dernier est topic.id = 3.
    Je ne souhaite récupérer que celui si, et si plus tard un autre topic est enregistré avec comme parent topic.categorie_id = 3, juste récupérer ce dernier, ceci bien entendu pour chaque catégorie.
    Je sais pas si mes explication sont assez compréhensible ?

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 134
    Points : 38 557
    Points
    38 557
    Billets dans le blog
    9
    Par défaut
    Ok en ce cas, il me semble plus simple de construire une CTE pour l'ensemble des topics de chaque catégorie dont la date de màj est la date maxi, puis de faire une requête sur cette CTE

  12. #12
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 134
    Points : 38 557
    Points
    38 557
    Billets dans le blog
    9
    Par défaut
    Soit quelque chose comme ca, à tester je n'ai pas créé les tables chez moi


    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    with tmp as
        (select mbr.id           AS mbrid, 
                mbr.pseudo       AS mbrps, 
                top.id           AS topid, 
                top.titre        AS topti, 
                top.date         AS topdt, 
                top.categorie_id AS topct
         from membres mbr
         inner join topic top
            on top.membre_id = mbr.id
         where top.date = 
              (select max(top.date) from topic subq
               where subq.categorie_id = top.categorie_id)
         )
     
    SELECT distinct 
           categorie.id AS catid, 
           categorie.titre, 
           categorie.description, 
           categorie.position, 
           tmp.mbrid AS iduser, 
           tmp.mbrps AS pseudo, 
           tmp.topid AS topic_id, 
           tmp.topti AS topic_titre, 
           tmp.topdt AS date_topic, 
           tmp.topct AS topic_cat_id
    FROM  categorie
    LEFT OUTER JOIN  tmp 
      ON tmp.catid = categorie.id
    ORDER BY  categorie.position ASC 
    LIMIT 0 , 30

  13. #13
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    Bonsoir,
    Merci pour vos réponse.
    Cependant je me retrouve avec une erreur mais je n'en trouve pas l'origine sur cette dernière requete :
    J'ai essayer différentes choses mais idem..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'tmp as (select mbr.id AS mbrid, mbr.pseudo AS mbrps, ' at line 1
    Une idée ??

  14. #14
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    J'ai deux idées que tu pourrais vérifier, d'une la syntaxe des CTE sous MySql, mais je pense que la précédente requête a été testée donc ca devrait etre correcte.

    Autre chose, vérifier si ta version de MySQL n'est pas out of date, et donc si elle ne serait pas trop vieille pour executer une CTE peut etre...

  15. #15
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    Bonjour,
    Après quelques recherches apparemment les CTE ne sont pas supporté par MySQL.

  16. #16
    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,

    Il suffit de la mettre en sous requete en table dérivée.

Discussions similaires

  1. [SQL] PB : Jointure SQL ne fonctionne pas..
    Par guillaumeIOB dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 13/09/2006, 14h03
  2. Réponses: 1
    Dernier message: 28/07/2006, 03h57
  3. [SQL] Eviter doublons dans un select (sans DISTINCT)
    Par renaud26 dans le forum PHP & Base de données
    Réponses: 40
    Dernier message: 11/07/2006, 17h07
  4. Réponses: 4
    Dernier message: 11/10/2005, 10h17
  5. [SQL/access] Doublon sur un champ
    Par kor dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/01/2005, 11h21

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