Tidak ada fungsi jendela, Anda dapat memesan tbl
dan gunakan variabel pengguna untuk menghitung sendiri peringkat atas partisi Anda (nilai "tanggal"):
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;
Perbarui
Jadi, apa yang dilakukan kueri itu?
Kami menggunakan variabel pengguna untuk "mengulang" melalui kumpulan hasil yang diurutkan, menambah atau mengatur ulang penghitung (@rank
) tergantung pada segmen bersebelahan mana dari kumpulan hasil (dilacak di @partition
) kita masuk.
Dalam kueri A kami menginisialisasi dua variabel pengguna. Dalam kueri B kami mendapatkan catatan tabel Anda dalam urutan yang kami butuhkan:pertama berdasarkan tanggal dan kemudian berdasarkan nilai. A dan B bersama-sama membuat tabel turunan, tbl_ordered
, yang terlihat seperti ini:
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
Ingat, kami tidak terlalu peduli dengan kolom dummy.rank
dan dummy.partition
— itu hanya kebetulan tentang bagaimana kita menginisialisasi variabel @rank
dan @partition
.
Dalam kueri C kita mengulang melalui catatan tabel turunan. Apa yang kami lakukan kurang lebih seperti yang dilakukan pseudocode berikut:
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)
Terakhir, kueri D memproyeksikan semua kolom dari C kecuali untuk kolom yang berisi @partition
(yang kami beri nama dummy
dan tidak perlu ditampilkan).