sql >> Base de Datos >  >> RDS >> Mysql

Asistir a la consulta MySQL de racha

Supongamos que su tabla es Event y las columnas son EventID y Name . Podemos determinar la secuencia (es decir, 1, 2, 3, etc.) en la que cada persona asistió a los eventos mediante la siguiente consulta:

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

Podemos aprovechar PersonalEventSequence para agrupar los eventos de cada persona en rachas:

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

Ahora que los eventos de cada persona están agrupados en rachas (¡con números de grupos de rachas ciertamente extraños!), podemos determinar la duración de las rachas de cada persona:

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

Ahora que conocemos la longitud de las rachas de cada persona, podemos determinar la longitud de la racha más larga de cada persona:

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

Notas:

  • El OP solo quería rachas actuales (es decir, rachas que incluyen el evento más reciente), pero dejo esa solución específica en manos del OP, ya que la solución general que se muestra aquí será aplicable a más programadores.
  • El código podría limpiarse utilizando vistas en lugar de subconsultas.
  • No he intentado ejecutar este código. Podría haber errores.