Mysql
 sql >> Base de données >  >> RDS >> Mysql

Requête MySQL Streak

Supposons que votre table est Event et les colonnes sont EventID et Name . Nous pouvons déterminer la séquence (c'est-à-dire 1, 2, 3, etc.) dans laquelle chaque personne a assisté aux événements par la requête suivante :

SELECT
  e1.Name, e1.EventID, COUNT(*) AS PersonalEventSequence
FROM
  Event e1
    INNER JOIN
  Event e2
    ON e1.Name = e2.Name AND e1.EventID >= e2.EventID
GROUP BY
  e1.Name, e1.EventID

Nous pouvons tirer parti de PersonalEventSequence pour regrouper les événements de chaque personne en séquences :

SELECT
  Name, EventID - PersonalEventSequence AS StreakGroup
FROM
  (
    SELECT
      e1.Name, e1.EventID, COUNT(*) AS PersonalEventSequence
    FROM
      Event e1
        INNER JOIN
      Event e2
        ON e1.Name = e2.Name AND e1.EventID >= e2.EventID
    GROUP BY
      e1.Name, e1.EventID
  ) AS SubQuery1

Maintenant que les événements de chaque personne sont regroupés en séquences (avec des nombres de StreakGroup certes étranges !), nous pouvons déterminer la longueur des séquences de chaque personne :

SELECT
  Name, StreakGroup, COUNT(*) AS StreakLength
FROM
  (
    SELECT
      Name, EventID - PersonalEventSequence AS StreakGroup
    FROM
      (
        SELECT
          e1.Name, e1.EventID, COUNT(*) AS PersonalEventSequence
        FROM
          Event e1
            INNER JOIN
          Event e2
            ON e1.Name = e2.Name AND e1.EventID >= e2.EventID
        GROUP BY
          e1.Name, e1.EventID
      ) AS SubQuery1
  ) SubQuery2
GROUP BY
  Name, StreakGroup

Maintenant que nous connaissons la longueur des séquences de chaque personne, nous pouvons déterminer la durée de la séquence la plus longue de chaque personne :

SELECT
  Name, MAX(StreakLength) AS PersonalRecordStreakLength
FROM
  (
    SELECT
      Name, StreakGroup, COUNT(*) AS StreakLength
    FROM
      (
        SELECT
          Name, EventID - PersonalEventSequence AS StreakGroup
        FROM
          (
            SELECT
              e1.Name, e1.EventID, COUNT(*) AS PersonalEventSequence
            FROM
              Event e1
                INNER JOIN
              Event e2
                ON e1.Name = e2.Name AND e1.EventID >= e2.EventID
            GROUP BY
              e1.Name, e1.EventID
          ) AS SubQuery1
      ) SubQuery2
    GROUP BY
      Name, StreakGroup
  ) SubQuery3
GROUP BY
  Name

Remarques :

  • L'OP ne voulait que les séquences actuelles (c'est-à-dire les séquences qui incluent le dernier événement), mais je laisse cette solution spécifique à l'OP pour qu'il la découvre puisque la solution générale présentée ici sera applicable à plus de programmeurs.
  • Le code pourrait être nettoyé en utilisant des vues au lieu de sous-requêtes.
  • Je n'ai pas essayé d'exécuter ce code. Il peut y avoir des erreurs.