Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Atendendo à consulta do Streak MySQL


Vamos supor que sua tabela seja Event e as colunas são EventID e Name . Podemos determinar a sequência (ou seja, 1, 2, 3, etc.) em que cada pessoa participou dos eventos pela seguinte 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 aproveitar PersonalEventSequence para agrupar os eventos de cada pessoa em sequências:
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

Agora que os eventos de cada pessoa estão agrupados em sequências (com números de StreakGroup reconhecidamente estranhos!), podemos determinar a duração das sequências de cada pessoa:
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

Agora que sabemos os comprimentos das raias de cada pessoa, podemos determinar o comprimento da raia mais longa de cada pessoa:
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:
  • O OP queria apenas as sequências atuais (ou seja, sequências que incluem o evento mais recente), mas estou deixando essa solução específica para o OP descobrir, pois a solução geral mostrada aqui será aplicável a mais programadores.
  • l>
  • O código pode ser limpo usando visualizações em vez de subconsultas.
  • Não tentei executar este código. Pode haver erros.