Partage
  • Partager sur Facebook
  • Partager sur Twitter

Requête sur 1 user, à faire sur tous les users

Sujet résolu
    31 juillet 2018 à 10:17:21

    Bonjour,

    Je viens vers vous car je ne trouve pas la solution à mon problème par moi même ...

    J'ai une table (voir screenshot ci-dessous) qui représente un utilisateur et qui contient des informations sur chaque utilisateurs

    J'ai également une table (voir screenshot ci-dessou) qui enregistre l'historique des états des comptes des utilisateurs, soit 'en cours de validation', 'validé', 'rejeté', etc ..

    Donc pour chaque utilisateur unique dans la table end_users, il peut y avoir plusieurs entrées dans la table end_user_status_histo (premièrement son compte a été en attente de valdiation, puis validé, puis clos par exemple).

    Avec la requête ci-dessous, j'arrive à récupérer le dernier état du compte enregistré pour 1 utilisateur donné en paramètre :

    SELECT id_status, date FROM end_user_status_histo WHERE id_end_user = :idUser ORDER BY date DESC LIMIT 1

    Cependant mon problème, est que je souhaiterais récupérer tous les utilisateurs dont le dernier enregistrement dans la table end_user_status_histo soit à 1 dans la colonne 'id_status', et la je sèche ... j'ai essayé de penser à des sous-requêtes pour tout faire en 1 fois mais je n'arrive pas à tomber sur quelque chose qui fonctionne.

    EDIT : j'ai tenté ça mais évidemment ca ne fonctionne pas :/

    SELECT e.lastname, e.firstname FROM end_users AS e INNER JOIN end_user_status_histo ON end_user_status_histo.id_end_user = end_users.id WHERE (SELECT id_status FROM end_user_status_histo WHERE e.id = e.id  ORDER BY date DESC LIMIT 1) = 1



    Pourriez vous m'aider s'il vous plait ?

    Cordialement

    -
    Edité par Mecadie 31 juillet 2018 à 10:26:51

    • Partager sur Facebook
    • Partager sur Twitter
    Hello World ! On en aura jamais fini d'apprendre !
      31 juillet 2018 à 11:17:07

      Bonjour,

      Mecadie a écrit:

      je souhaiterais récupérer tous les utilisateurs dont le dernier enregistrement dans la table end_user_status_histo soit à 1 dans la colonne 'id_status'

      Il faut commencer par retrouver le dernier status par user :

      -- Dernier status par user
      SELECT
      	id_end_user,
      	MAX(date) AS max_date
      FROM end_user_status_histo
      GROUP BY id_end_user

      Ensuite il faut retrouver les données associées en utilisant ce résultat comme sous-requête, et ne choisir que ceux qui ont un id_status = 1 :

      SELECT U.*
      FROM
      	(
      		-- Dernier status par user
      		SELECT
      			id_end_user,
      			MAX(date) AS max_date
      		FROM end_user_status_histo
      		GROUP BY id_end_user
      	) LS
      		INNER JOIN end_user_status_histo SH
      			ON LS.id_end_user = SH.id_end_user
      			AND LS.max_date = SH.date
      		INNER JOIN end_users U
      			ON SH.id_end_user = U.id
      WHERE SH.id_status = 1

      Cette requête devrait te retourner tous les utilisateurs dont le dernier statut est 1.

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        31 juillet 2018 à 11:21:45

        Benzouye a écrit:

        Bonjour,

        Mecadie a écrit:

        je souhaiterais récupérer tous les utilisateurs dont le dernier enregistrement dans la table end_user_status_histo soit à 1 dans la colonne 'id_status'

        Il faut commencer par retrouver le dernier status par user :

        -- Dernier status par user
        SELECT
        	id_end_user,
        	MAX(date) AS max_date
        FROM end_user_status_histo
        GROUP BY id_end_user

        Ensuite il faut retrouver les données associées en utilisant ce résultat comme sous-requête, et ne choisir que ceux qui ont un id_status = 1 :

        SELECT U.*
        FROM
        	(
        		-- Dernier status par user
        		SELECT
        			id_end_user,
        			MAX(date) AS max_date
        		FROM end_user_status_histo
        		GROUP BY id_end_user
        	) LS
        		INNER JOIN end_user_status_histo SH
        			ON LS.id_end_user = SH.id_end_user
        			AND LS.max_date = SH.date
        		INNER JOIN end_users U
        			ON SH.id_end_user = U.id
        WHERE SH.id_status = 1

        Cette requête devrait te retourner tous les utilisateurs dont le dernier statut est 1.


        Bonjour, et merci de ta réponse !

        En cherchant un peu mieux sur le net j'ai trouvé une requête que j'ai adapté à ma bdd et ça a l'air de retourner les bon résultats j'ai fait quelques test, que penses tu de cette requête ?

        SELECT t1.*, t2.*, t3.lastname, t3.firstname, t3.offer, t3.groupe, t3.network, t1.date 
          FROM `end_user_status_histo` as t1 
          left outer join end_user_status_histo as t2 on t1.date < t2.date and t1.id_end_user = t2.id_end_user 
          LEFT OUTER JOIN end_users as t3 ON t1.id_end_user = t3.id where t2.date is null having t1.id_status = 1



        • Partager sur Facebook
        • Partager sur Twitter
        Hello World ! On en aura jamais fini d'apprendre !
          31 juillet 2018 à 11:29:33

          Oui, cette requête est fonctionnelle, elle sélectionne les historiques qui n'ont pas d'historique plus vieux (t2.date IS NULL).

          Par contre elle fait une jointure externe (LEFT JOIN) ce qui me paraît moins performant que la sous-requête.

          Si tu n'as pas beaucoup d'enregistrements dans les tables user et historique, tu peux garder celle-ci, mais dès que le volume de données va augmenter la jointure gauche va ramer ...

          Au passage, tu peux rationnaliser ainsi :

          SELECT
          	t1.*,
          	t2.*,
          	t3.lastname,
          	t3.firstname,
          	t3.offer,
          	t3.groupe,
          	t3.network,
          	t1.date
          FROM
          	end_users as t3
          		INNER JOIN end_user_status_histo as t1
          			ON t1.id_end_user = t3.id
          		LEFT JOIN end_user_status_histo as t2
          			ON t1.date < t2.date
          			AND t1.id_end_user = t2.id_end_user
          WHERE
          	t2.date is null
          	AND t1.id_status = 1

          -
          Edité par Benzouye 31 juillet 2018 à 11:29:59

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            31 juillet 2018 à 11:45:01

            Merci alors, le problème est résolu !

            Bonne journée

            • Partager sur Facebook
            • Partager sur Twitter
            Hello World ! On en aura jamais fini d'apprendre !

            Requête sur 1 user, à faire sur tous les users

            × 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