だから、私は次のようなテーブルを持っています:
sn color value
1 red 4
2 red 8
3 green 5
4 red 2
5 green 4
6 green 3
次に、各色の最新の2行が必要です。例:
2 red 8
4 red 2
5 green 4
6 green 3
色ごとに個別のクエリを使用する以外に、それを行う方法は?
ありがとう
SELECT sn, color, value
FROM (
SELECT
sn,
color,
value,
DENSE_RANK() OVER (PARTITION BY color ORDER BY sn) AS r
FROM table
) AS t
WHERE t.r <= 2;
あなたはそれらの特別な変数を使用する必要があります。 このようなもの
これは、「greatest-n-per-group」問題のバリエーションです。 MySQLだけが実装している場合は、ウィンドウ関数またはLATERAL
結合(_CROSS/OUTER APPLY
_とも呼ばれる)で使用できます。*。
これが機能する1つの方法です。私はそれを「貧乏人の十字架適用」と呼びます:
_select t.*
from
( select distinct color from tbl ) as td -- for every colour
left join -- join to the table
tbl as t -- and get all rows
on t.color = td.color -- with that color
and t.sn >= coalesce( -- and sn bigger or equal than
( select ti.sn -- the 2nd higher sn value
from tbl as ti
where ti.color = td.color
order by ti.sn desc
limit 1 offset 1 -- 1 + 1st = 2nd
), -9223372036854775808 -- the smallest possible bigint value,
) ; -- to cover cases of colours
-- with a single appearance, where
-- the subquery returns NULL
_
dbfiddle.uk でテストされています。 _(color, sn)
_または_(color, sn, value)
_のインデックスがこのクエリで使用されます。異なるcolor
値が少ししかない場合は、非常に効率的です。
*:MySQLのフォークであるMariaDBは実際にウィンドウ関数を実装しているため、ROW_NUMBER()
、RANK()
またはDENSE_RANK()
などのランキング関数を使用したソリューションがそこで機能します。