Chybí funkce okna, můžete si objednat tbl
a pomocí uživatelských proměnných si sami vypočítejte pořadí svých oddílů (hodnoty "datum"):
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;
Aktualizovat
Co tedy dělá tento dotaz?
Používáme uživatelské proměnné „procházet“ seřazenou sadu výsledků, zvyšovat nebo vynulovat počítadlo (@rank
) podle toho, který souvislý segment sady výsledků (sledováno v @partition
) jsme tam.
V dotazu A inicializujeme dvě uživatelské proměnné. V dotazu B získáme záznamy vaší tabulky v pořadí, které potřebujeme:nejprve podle data a poté podle hodnoty. A a B společně vytvoří odvozenou tabulku tbl_ordered
, vypadá to nějak takto:
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
Pamatujte, že nás ve skutečnosti nezajímají sloupce dummy.rank
a dummy.partition
— jsou to jen náhody toho, jak inicializujeme proměnné @rank
a @partition
.
V dotazu C procházíme záznamy odvozené tabulky. To, co děláme, je víceméně to, co dělá následující pseudokód:
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)
Nakonec zadejte dotaz D promítne všechny sloupce z C kromě pro sloupec obsahující @partition
(který jsme nazvali dummy
a nemusí se zobrazovat).