Fraværende vinduesfunktioner kan du bestille tbl
og brug brugervariable til selv at beregne rang over dine partitioner ("datoværdier"):
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;
Opdater
Så hvad gør den forespørgsel?
Vi bruger brugervariabler at "loope" gennem et sorteret resultatsæt, øge eller nulstille en tæller (@rank
) afhængigt af hvilket sammenhængende segment af resultatsættet (sporet i @partition
) vi er med.
I forespørgsel A vi initialiserer to brugervariabler. I forespørgsel B vi får optegnelserne over dit bord i den rækkefølge, vi har brug for:først efter dato og derefter efter værdi. A og B laver sammen en afledt tabel, tbl_ordered
, der ser sådan her ud:
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
Husk, vi er ligeglade med kolonnerne dummy.rank
og dummy.partition
— de er blot tilfældigheder af, hvordan vi initialiserer variablerne @rank
og @partition
.
I forespørgsel C vi går gennem den afledte tabels poster. Det, vi gør, er mere eller mindre, hvad den følgende pseudokode gør:
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)
Forespørg endelig D projicerer alle kolonner fra C undtagen for kolonnen med @partition
(som vi kaldte dummy
og behøver ikke at blive vist).