Partage
  • Partager sur Facebook
  • Partager sur Twitter

Récupérer les derniers messages sans doublons ?

J'ai beau tenté je n'y arrive pas

    21 septembre 2021 à 22:50:45

    Bonjour à tous,

    Je tente de récupérer le dernier message écrit des groupes dans lesquels l'utilisateur est,

    mais s'il n y a pas de message, j'aimerais que les champs groups_chat.message & groups_chat.date restent à NULL

    Voici ce que j'ai pu faire : 

    SELECT residents_groups.group_id, groups.group_name, groups.group_image, groups.owner, residents.username_chat, groups_chat.message, groups_chat.date 
    FROM `groups` 
    INNER JOIN residents_groups 
    ON groups.id = residents_groups.group_id 
    LEFT JOIN groups_chat 
    ON groups.id = groups_chat.group_id 
    LEFT JOIN residents ON groups_chat.resident_id = residents.id 
    WHERE residents_groups.resident_id = 31 

     En voici le résultat : 


    On peux apercevoir que le groupe "Groupe d'amis" apparait plusieurs fois car il y a trois messages, mais j'aimerais juste afficher le dernier et s'il y en a pas qu'il marque "NULL"

    Pouvez-vous m'aider ?

    Voici mes tables :

    Update : J'ai tenté cette requête : 

    SELECT residents_groups.group_id, groups.group_name, residents.username_chat, groups.group_image, groups.owner, groups_chat.message, groups_chat.date 
    		FROM `groups` 
    		INNER JOIN residents_groups 
    		ON groups.id = residents_groups.group_id 
    		LEFT JOIN groups_chat 
    		ON groups.id = groups_chat.group_id 
    
    		INNER JOIN residents 
    		ON groups_chat.resident_id = residents.id
    		WHERE groups_chat.id in (select max(groups_chat.id) from groups_chat group by groups_chat.group_id) 
    		AND residents_groups.resident_id = 31 ORDER BY `groups_chat`.`date` DESC

    Mais du coup il ne m'affiche uniquement que les message et non pas tout les groupes..

    -
    Edité par ChedyEltabaa 21 septembre 2021 à 23:00:03

    • Partager sur Facebook
    • Partager sur Twitter
      22 septembre 2021 à 1:31:07

      Je pense que tu galérerais moins à faire comme suit :

      3 tables : UTILISATEURS, GROUPES, MESSAGES

      2 jointures : Appartenir (entre UTILISATEURS et GROUPES), Écrire (entre UTILISATEURS et MESSAGES)

      Appartenir aurait 2 clés étrangères :

      #utilisateur qui fait référence à la table UTILISATEURS et #groupe qui fait référence à la table GROUPES

      Écrire aurait 2 clés étrangères et une colonne periode de type DATETIME. periode répond au Quand de la méthode Q,Q,O,Q,C,C,P. Utile ici puisque tu veux trier par date : #utilisateur qui fait référence à la table UTILISATEURS, #message qui fait référence à la table MESSAGES, et la colonne periode.

      Normalement, en faisant ainsi, tu n'auras pas de NULL.

      Pour les cardinalités :

      Un utilisateur appartient à 1,n groupes. Un groupe contient 1,n utilisateurs.

      Un utilisateur écrit 0,n messages. Un message est écrit par 1,n (n si la messagerie est non chiffrée : on ne stocke qu'un même message une seule fois, exemple : "Salut ça va ?" écrit très souvent) utilisateurs.

      • Partager sur Facebook
      • Partager sur Twitter
        22 septembre 2021 à 8:48:06

        Bonjour,

        Je plussoie la remarque de CR7.

        Le modèle serait :

        • utilisateur ( id_utilisateur [pk], nom, prenom, etc. )
        • groupe ( id_groupe [pk], nom )
        • utilisateur_groupe ( id_utilisateur [pk][fk], id_groupe [pk][fk] )
        • message ( id_message [pk], id_groupe [fk], id_utilisateur [fk], date_creation, contenu )

        Je n'ai pas saisi la position du building et son utilisation dans ce modèle, il faudra clarifier ce point pour savoir où le positionner ...

        Concernant la demande initiale, il faut absolument passer par une sous-requête qui remonte le dernier message par groupe ...

        • Partager sur Facebook
        • Partager sur Twitter
        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
          22 septembre 2021 à 9:37:56

          bonjour,

          Benzouye, votre explication m'a bien aidé!! Merci beaucoup

          • Partager sur Facebook
          • Partager sur Twitter
            23 septembre 2021 à 17:20:04

            Bonsoir et merci pour vos réponses assez constructives,

            J'ai tenté pas mal de choses mais je n'y suis toujours pas, si vous avez des exemples SQL à donner je suis preneur.

            CR7 ta réponse est très constructive mais je pense n'avoir pas très bien compris..

            Pour te répondre @Benzouye, la position du building est juste pour savoir dans quel building se trouve les groupes, 

            donc inutilisable pour ma requête actuelle (à ignorer)

            • Partager sur Facebook
            • Partager sur Twitter
              23 septembre 2021 à 17:30:39

              ChedyEltabaa a écrit:

              la position du building est juste pour savoir dans quel building se trouve les groupes

              Ok, mais un groupe peut être associé à plusieurs buildings ? et un building à plusieurs groupes ?

              Et qu'en est-il des résidents ? Un résident peut-il être lié à un ou plusieurs building et un building peut-il être lié à un ou plusieurs résident ?

              Est-ce que le groupe ne serait pas la même chose que le building en fait ?

              Selon ma logique, sans connaître le projet, c'est le résident qui est dans un building (et un seul) donc un groupe c'est en fait tous les résidents d'un même building ...

              ChedyEltabaa a écrit:

              J'ai tenté pas mal de choses mais je n'y suis toujours pas, si vous avez des exemples SQL à donner je suis preneur

              As-tu modifié ton modèle comme proposé ? ou es-tu toujours avec ton modèle bancale ?

              Ma proposition sans chambouler trop les choses serait :

              CREATE TABLE building (
              	id_building INT UNSIGNED NOT NULL AUTO_INCREMENT,
              	name VARCHAR(100) NOT NULL,
              	PRIMARY KEY ( id_building )
              ) Engine=InnoDB;
              
              CREATE TABLE resident (
              	id_resident INT UNSIGNED NOT NULL AUTO_INCREMENT,
              	id_building INT UNSIGNED NOT NULL,
              	pseudo VARCHAR(100) NOT NULL,
              	email VARCHAR(100) NOT NULL,
              	password VARCHAR(60) NOT NULL,
              	PRIMARY KEY ( id_resident ),
              	FOREIGN KEY ( id_building ) REFERENCES building ( id_building )
              ) Engine=InnoDB;
              
              CREATE TABLE groups (
              	id_group INT UNSIGNED NOT NULL AUTO_INCREMENT,
              	id_owner INT UNSIGNED NOT NULL,
              	name VARCHAR(255) NOT NULL,
              	image VARCHAR(255),
              	PRIMARY KEY ( id_group ),
              	FOREIGN KEY ( id_owner ) REFERENCES resident ( id_resident )
              ) Engine=InnoDB;
              
              CREATE TABLE resident_group (
              	id_group INT UNSIGNED NOT NULL,
              	id_resident INT UNSIGNED NOT NULL,
              	PRIMARY KEY ( id_group, id_resident ),
              	FOREIGN KEY ( id_group ) REFERENCES groups ( id_groupe ),
              	FOREIGN KEY ( id_resident ) REFERENCES resident ( id_resident )
              ) Engine=InnoDB;
              
              CREATE TABLE message (
              	id_message INT UNSIGNED NOT NULL AUTO_INCREMENT,
              	content TEXT NOT NULL,
              	date_create DATETIME NOT NULL,
              	id_group INT UNSIGNED NOT NULL,
              	id_resident INT UNSIGNED NOT NULL,
              	PRIMARY KEY ( id_resident ),
              	FOREIGN KEY ( id_group, id_resident ) REFERENCES resident_group ( id_group, id_resident )
              ) Engine=InnoDB;

              Et la requête désirée serait ici :

              SELECT
              	G.id_group,
              	G.name as group_name,
              	M.date_create AS last_message_date
              	M.content AS last_message_content,
              	R.pseudo AS last_message_pseudo
              FROM
              	(
              		-- Date dernier message par groupe
              		SELECT id_group, MAX( date_create ) AS max_date
              		FROM message
              		GROUP BY id_group
              	) MD
              		INNER JOIN message M
              			ON M.id_group = MD.id_group
              			AND M.date_create = MD.max_date
              		INNER JOIN groups G
              			ON MD.id_group = G.id_group
              		INNER JOIN resident_group RG
              			ON G.id_group = RG.id_group
              		INNER JOIN resident R
              			ON M.id_resident = R.id_resident
              WHERE RG.id_resident = 'id résident connecté'
              ORDER BY M.date_create

              Mais si les groupes sont seulement constitués des résidents d'un building alors tout cela se simplifie grandement en fait ... en tout cas en nombre de tables ...

              -
              Edité par Benzouye 23 septembre 2021 à 18:12:18

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                26 septembre 2021 à 23:38:15

                ChedyEltabaa a écrit:

                CR7 ta réponse est très constructive mais je pense n'avoir pas très bien compris..

                Je ne sais pas comment mieux l'expliquer mieux.

                • Partager sur Facebook
                • Partager sur Twitter

                Récupérer les derniers messages sans doublons ?

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown