Mysql
 sql >> Database >  >> RDS >> Mysql

Frequentando la serie di query MySQL

Supponiamo che la tua tabella sia Event e le colonne sono EventID e Name . Possiamo determinare la sequenza (cioè, 1, 2, 3, ecc.) in cui ogni persona ha partecipato agli eventi con la seguente query:

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

Possiamo sfruttare PersonalEventSequence per raggruppare gli eventi di ogni persona in serie:

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

Ora che gli eventi di ogni persona sono raggruppati in serie (avendo certamente numeri strani di StreakGroup!), possiamo determinare la durata delle serie di ciascuna 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

Ora che conosciamo le lunghezze delle serie consecutive di ogni persona, possiamo determinare la lunghezza della serie più lunga di ciascuna 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

Note:

  • L'OP voleva solo le serie correnti (ovvero le serie che includono l'ultimo evento), ma lascio quella soluzione specifica all'OP per capire poiché la soluzione generale mostrata qui sarà applicabile a più programmatori.
  • Il codice potrebbe essere ripulito utilizzando Visualizzazioni anziché sottoquery.
  • Non ho provato a eseguire questo codice. Potrebbero esserci degli errori.