Partage
  • Partager sur Facebook
  • Partager sur Twitter

[MySQL 5.7] Filtrage par date - tableau de scores

LEFT JOIN? BETWEEN DATE?

Sujet résolu
    10 septembre 2022 à 18:38:03

    Bonjour à tous,

    Je me creuse la tête sans arriver à trouver de solution depuis un moment, alors je poste ici, pour qu'on creuse à plusieurs! :D

    J'ai une Table 'users_score' comme exemple ci-dessous

    iduser_iduser_scorescore_date
     1  1  10 2022-08-29
     2  4  5 2022-08-30
     3  2  2 2022-09-03
     4  2  3 2022-09-01
     5  3  8 2022-08-30
     6  3  3 2022-08-26
     7  4  7 2022-08-29
    8  1  9 2022-09-04
     9  1  5 2022-08-30
    Je souhaite un affichage type Top 10 pour une période précise.
    Mais avant tout, sans choix période j'utilise la requête SQL suivante pour n'afficher qu'un seul (meilleur) score de chaque user
    SELECT m.*
    FROM users_score m          
    LEFT JOIN users_score b      
    ON m.user_id = b.user_id
    AND m.user_score < b.user_score
    WHERE b.user_score IS NULL
    ORDER BY user_score DESC
    LIMIT10

     Ce qui me fait un bon tableau des scores:

    iduser_iduser_scorescore_date
    1 1 10 2022-08-29
    2 3 8 2022-08-30
    3 4 7 2022-08-29
    4 2 3 2022-09-01

     Mais ça se complique avec un choix de date avec "BETWEEN score_date" et la première et la dernière date du mois, ou même encore avec "MONTH(score_date) = '9'" pour le mois de septembre par exemple.

    Je ne sais pas ou le placer dans la requête pour me produire le résultat escompté.

    Je n'ai aucun résultat du même ordre que le tableau ci-dessus.

    Auriez vous des pistes? une table temporaire? une sous-requête? 

    D'avance merci pour votre aide précieuse, je suis au fond du rouleau ! :p

    -
    Edité par Ktz_13 10 septembre 2022 à 20:00:24

    • Partager sur Facebook
    • Partager sur Twitter
      11 septembre 2022 à 10:29:04

      Bonjour,

      Imaginons que l'utilisateur 2 a un meilleur score à 8 mais pour deux dates différentes de la période souhaitée ... comment voudrais-tu afficher le résultat ? En l'état ta requête afficherai les deux dates ...

      Je commencerai par calculer le meilleur score par utilisateur sur la période souhaitée :

      -- Meilleur score par utilisateur
      -- Pour le mois de septembre 2022
      SELECT
      	user_id,
      	MAX( user_score ) AS score
      FROM users_score
      WHERE
      	YEAR( score_date ) = 2022
      	AND MONTH( score_date ) = 9

      Ensuite on peut utiliser cela comme sous-requête :

      SELECT
      	S.id,
      	S.user_id,
      	S.user_score,
      	MAX( S.score_date ) max_date
      FROM
      	(
      		-- Meilleur score par utilisateur
      		-- Pour septembre 2022
      		SELECT
      			user_id,
      			MAX( user_score ) AS max_score
      		FROM users_score
      		WHERE
      			YEAR( score_date ) = 2022
      			AND MONTH( score_date ) = 9
      	) MS
      	
      		INNER JOIN users_score S
      			ON MS.user_id = S.user_id
      			AND MS.max_score = S.user_score
      WHERE
      	YEAR( S.score_date ) = 2022
      	AND MONTH( S.score_date ) = 9
      GROUP BY
      	S.id,
      	S.user_id,
      	S.user_score
      ORDER BY S.user_score DESC

      Pour mon exemple, cette requête n'afficherai que le score de la date la plus récente dans la période.

      Je reconnais que c'est un brin tordu, mais je ne vois pas vraiment comment faire autrement ...

      -
      Edité par Benzouye 11 septembre 2022 à 10:29:54

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        12 septembre 2022 à 15:25:19

        Bonjour @benzouze,

        Merci pour ton retour rapide.

        J'ai toujours un soucis, même épurée cette requête ne me retourne que des résultats vides... l'as-tu essayé?

        Merci encore

        • Partager sur Facebook
        • Partager sur Twitter
          12 septembre 2022 à 22:11:31

          Je ne l'ai pas essayé, sans jeu de données ce n'est pas parlant...

          Peux-tu poster la requête que tu exécutes de ton côté ?

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            13 septembre 2022 à 11:07:28

            Bonjour Benzouye,

            Voici un jeu de données:


            CREATE TABLE IF NOT EXISTS `users_score` (
              `id` int(11) NOT NULL AUTO_INCREMENT,
              `user_id` int(11) NOT NULL,
              `user_score` int(5) NOT NULL,
              `score_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
              PRIMARY KEY (`id`)
            ) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=latin1;


            INSERT INTO `users_score` (`id`, `user_id`, `user_score`, `score_date`) VALUES
            (1, 15, 5, '2022-08-26 09:51:02'),
            (2, 3, 2, '2022-08-26 11:47:00'),
            (3, 1, 3, '2022-08-26 12:08:39'),
            (4, 1, 2, '2022-08-26 14:31:35'),
            (5, 1, 3, '2022-08-26 15:30:16'),
            (6, 6, 9, '2022-08-26 15:42:07'),
            (7, 9, 6, '2022-08-29 10:41:48'),
            (8, 1, 8, '2022-09-12 17:35:40'),
            (9, 4, 15, '2022-08-29 14:59:23'),
            (10, 1, 4, '2022-08-30 10:08:51'),
            (11, 1, 6, '2022-08-30 11:33:14'),
            (12, 1, 0, '2022-08-30 17:54:15'),
            (13, 1,  0, '2022-08-30 17:54:39'),
            (14, 1,  2, '2022-08-31 11:18:11'),
            (15, 4,  17, '2022-09-01 13:49:12'),
            (16, 1,  8, '2022-09-03 15:11:49'),
            (17, 1,  1, '2022-09-04 12:12:07'),
            (18, 3,  26, '2022-08-30 16:00:29'),
            (19, 1,  0, '2022-09-06 08:36:27'),
            (20, 1,  3, '2022-09-06 08:36:50'),
            (21, 1,  3, '2022-09-07 10:34:12'),
            (22, 1,  1, '2022-09-13 10:18:18'),
            (23, 1,  1, '2022-09-07 20:25:23'),
            (24, 1,  2, '2022-09-09 11:52:50');

            La requête que j'essaie d'améliorer est la suivante:

            SELECT m.*
            FROM (SELECT*FROM users_score WHEREMONTH(score_date)  = '9' ) m
            LEFT JOIN (SELECT*FROM users_score WHEREMONTH(score_date)  = '9' ) b
            ON m.user_id = b.user_id
            AND m.user_score < b.user_score
            WHERE b.user_score ISNULL
            ORDER BY m.user_score DESC
            LIMIT10

            Car j'ai pour l'instant évidemment des résultats avec 2 fois le même user si égalité de score.

            J'essaie de combiner avec ta requête pour comprendre, car même en retirant le WHERE dans ta requête pour sélectionner le MONTH et YEAR, j'ai des résultats vides.

            Mais c'est exactement ça, j'aimerai ne pas avoir deux lignes avec le même user, peu importe la date d'ailleurs puisque je ne l'affiche pas.

            Merci beaucoup encore de te pencher dessus! Top

            -
            Edité par Ktz_13 13 septembre 2022 à 15:44:40

            • Partager sur Facebook
            • Partager sur Twitter
              13 septembre 2022 à 13:55:25

              My mistake ... J'ai oublié le GROUP BY dans la sous-requête, et j'ai laissé l'id dans le GROUP BY de la requête principale ...

              La requête corrigée est :

              SELECT
              	S.user_id,
              	S.user_score,
              	MAX( S.score_date ) max_date
              FROM
              	(
              		-- Meilleur score par utilisateur
              		-- Pour septembre 2022
              		SELECT
              			user_id,
              			MAX( user_score ) AS max_score
              		FROM users_score
              		WHERE
              			YEAR( score_date ) = 2022
              			AND MONTH( score_date ) = 9
              		GROUP BY user_id
              	) MS
              	 
              		INNER JOIN users_score S
              			ON MS.user_id = S.user_id
              			AND MS.max_score = S.user_score
              WHERE
              	YEAR( S.score_date ) = 2022
              	AND MONTH( S.score_date ) = 9
              GROUP BY
              	S.user_id,
              	S.user_score
              ORDER BY S.user_score DESC

              Qui, pour ton jeu de données retourne :



              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                13 septembre 2022 à 15:44:29

                Top, vraiment merci, c'est parfait, c'est le résultat escompté! :p

                Merci Benzouye!

                • Partager sur Facebook
                • Partager sur Twitter

                [MySQL 5.7] Filtrage par date - tableau de scores

                × 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