Presto, Hive にある行番号や順位を振る関数の違いがややこしくて覚えられないのでまとめておく。
ちなみに「どれが速いか」についてはわかっていないので、わかる方がいたらコメント頂けると嬉しい。
Presto
WITH tbl AS (
SELECT val
FROM (SELECT ARRAY[100, 200, 200, 300] AS arr) AS t
CROSS JOIN UNNEST(arr) AS t(val)
)
SELECT
val,
RANK() OVER (ORDER BY val),
DENSE_RANK() OVER (ORDER BY val),
ROW_NUMBER() OVER (ORDER BY val)
FROM tbl
RANK | DENSE_RANK | ROW_NUMBER | |
---|---|---|---|
100 | 1 | 1 | 1 |
200 | 2 | 2 | 2 |
200 | 2 | 2 | 3 |
300 | 4 | 3 | 4 |
- 同じの値があった場合、
RANK
は次の順位を飛ばすがDENSE_RANK
は飛ばさない -
ROW_NUMBER
は同じの値でも違う番号を振る
Hive
Hive 0.11 以前は ROW_NUMBER
が使えなかったが、最近の Hive では使えるので Presto と同じように使うことが出来る。
WITH tbl AS (
SELECT EXPLODE(ARRAY(100, 200, 200, 300)) AS val
)
SELECT
val,
RANK() OVER (ORDER BY val),
DENSE_RANK() OVER (ORDER BY val),
ROW_NUMBER() OVER (ORDER BY val)
FROM tbl
RANK | DENSE_RANK | ROW_NUMBER | |
---|---|---|---|
100 | 1 | 1 | 1 |
200 | 2 | 2 | 2 |
200 | 2 | 2 | 3 |
300 | 4 | 3 | 4 |
また、Treasure Data の Hive には TD_X_RANK
という UDF がある。
WITH tbl AS (
SELECT "a" AS key, val
FROM (SELECT EXPLODE(ARRAY(100, 200, 200, 300)) AS val) AS t
ORDER BY key
)
SELECT
key,
val,
TD_X_RANK(key)
FROM tbl
key | val | TD_X_RANK |
---|---|---|
a | 300 | 1 |
a | 200 | 2 |
a | 200 | 3 |
a | 100 | 4 |
- サブクエリであらかじめ
ORDER BY key
もしくはCLUSTER BY key
しておく必要がある -
key
ごとに区切って行番号が振られる-
ROW_NUMBER() OVER (PARTITION BY key)
と同じ
-
今の Hive は ROW_NUMBER
があるのでそっちを使えばいいのでは?と思うのだけど、 TD_X_RANK
のほうがパフォーマンスが良い、とかそういうのあるのだろうか。