Afwezige vensterfuncties, u kunt tbl
bestellen en gebruik gebruikersvariabelen om zelf de rangorde over uw partities ("datum"-waarden) te berekenen:
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;
Bijwerken
Dus, wat doet die zoekopdracht?
We gebruiken gebruikersvariabelen om door een gesorteerde resultatenset te "lopen" en een teller te verhogen of te resetten (@rank
) afhankelijk van welk aaneengesloten segment van de resultatenset (bijgehouden in @partition
) we doen mee.
In zoekopdracht A we initialiseren twee gebruikersvariabelen. In zoekopdracht B we krijgen de records van uw tafel in de volgorde die we nodig hebben:eerst op datum en dan op waarde. Een en B maak samen een afgeleide tabel, tbl_ordered
, dat ziet er ongeveer zo uit:
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
Onthoud dat we niet echt om de kolommen dummy.rank
geven en dummy.partition
— het zijn gewoon toevalligheden van hoe we de variabelen @rank
initialiseren en @partition
.
In zoekopdracht C we doorlopen de records van de afgeleide tabel. Wat we doen is min of meer wat de volgende pseudocode doet:
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)
Zoek ten slotte naar D projecteert alle kolommen van C behalve voor de kolom met @partition
(die we dummy
noemden en hoeven niet weergegeven te worden).