Mysql
 sql >> Datenbank >  >> RDS >> Mysql

innerhalb von Gruppensortierungen in mysql

Fehlende Fensterfunktionen können Sie tbl bestellen und verwenden Sie Benutzervariablen, um den Rang über Ihre Partitionen ("Datums"-Werte) selbst zu berechnen:

SELECT "date",                                                -- D) Desired columns
       id,
       value,
       rank
  FROM (SELECT "date",                                        -- C) Rank by date
               id,
               value,
               CASE COALESCE(@partition, "date")
                 WHEN "date" THEN @rank := @rank + 1
                 ELSE             @rank := 1
               END AS rank,
               @partition := "date" AS dummy
          FROM (SELECT @rank := 0 AS rank,                    -- A) User var init
                       @partition := NULL AS partition) dummy
               STRAIGHT_JOIN
               (  SELECT "date",                              -- B) Ordering query
                         id,
                         value
                    FROM tbl
                ORDER BY date, value) tbl_ordered;

Aktualisieren

Also, was macht diese Abfrage?

Wir verwenden Benutzervariablen um eine sortierte Ergebnismenge zu "schleifen", einen Zähler zu inkrementieren oder zurückzusetzen (@rank ) abhängig davon, welches zusammenhängende Segment der Ergebnismenge (verfolgt in @partition ) Wir sind dabei.

In Abfrage A Wir initialisieren zwei Benutzervariablen. In Abfrage B Wir erhalten die Datensätze Ihrer Tabelle in der von uns benötigten Reihenfolge:zuerst nach Datum und dann nach Wert. A und B bilden zusammen eine abgeleitete Tabelle, tbl_ordered , das sieht etwa so aus:

rank | partition | "date" |  id  | value 
---- + --------- + ------ + ---- + -----
  0  |   NULL    |   d1   |  id2 |    1
  0  |   NULL    |   d1   |  id1 |    2
  0  |   NULL    |   d2   |  id1 |   10
  0  |   NULL    |   d2   |  id2 |   11

Denken Sie daran, dass wir uns nicht wirklich um die Spalten dummy.rank kümmern und dummy.partition – das sind nur Zufälle, wie wir die Variablen @rank initialisieren und @partition .

In Abfrage C Wir durchlaufen die Datensätze der abgeleiteten Tabelle. Was wir tun, ist mehr oder weniger das, was der folgende Pseudocode tut:

rank      = 0
partition = nil

foreach row in fetch_rows(sorted_query):
  (date, id, value) = row

  if partition is nil or partition == date:
    rank += 1
  else:
    rank = 1

  partition = date

  stdout.write(date, id, value, rank, partition)

Fragen Sie abschließend D ab projiziert alle Spalten von C außer für die Spalte, die @partition enthält (die wir dummy genannt haben und müssen nicht angezeigt werden).