- カテゴリのリストを準備
- 各カテゴリごとに上位数件を抽出するSELECT文(SELECT ~ FROM ~ ORDER BY ~ LIMIT n)を発行
- (必要であれば)結果をまとめる
1 | SELECT * FROM ( SELECT *, rank() over (PARTITION BY category_id ORDER BY quantity DESC ) as rank FROM sample_table ) a WHERE rank < n; |
環境
今回実際に利用した各ソフトウェアのバージョンは以下のとおりである。- Hadoop
- 2.6.0.2.2.0.0-2041
- hive
- 0.14.0.2.2.0.0-2041
- tez
- 0.5.2.2.2.0.0-2041
テストデータ準備
今回は以下のようなデータを準備して、それに対してクエリを発行させる。区切り文字はタブで、各カラムはそれぞれ商品ID、ジャンルID、商品名、売上件数を表している。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 a book1 100 2 b fashion1 10 3 a book2 1000 4 c food1 1 5 c food2 10 6 b fashion2 100 7 d medicine1 100 8 b fashion3 1 9 b fashion4 10 10 b fashion5 1 11 c food3 100 12 a book3 10 13 a book4 1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | $ hive use test ; CREATE TABLE test_item_order_data( item_id bigint, genre_id string, item_name string, quantity bigint ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' ; LOAD DATA LOCAL INPATH "/path/to/test data/test.dat" OVERWRITE INTO TABLE test_item_order_data; SELECT * FROM test_item_order_data; 1 a book1 100 2 b fashion1 10 3 a book2 1000 4 c food1 1 5 c food2 10 6 b fashion2 100 7 d medicine1 100 8 b fashion3 1 9 b fashion4 10 10 b fashion5 1 11 c food3 100 12 a book3 10 13 a book4 1 |
クエリ実行
冒頭で紹介したrank関数を使ったクエリをテストデータが入ったテーブルに適用すると以下のようなクエリになる。ここでは上位3件を抽出している。
ちなみに、tezを使う方が速いのでtezを使っているが必須ではない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | set hive.execution.engine=tez; SELECT *, rank() over (PARTITION BY genre_id ORDER BY quantity DESC) as rank FROM test_item_order_data; 3 a book2 1000 1 1 a book1 100 2 12 a book3 10 3 13 a book4 1 4 6 b fashion2 100 1 9 b fashion4 10 2 2 b fashion1 10 2 8 b fashion3 1 4 10 b fashion5 1 4 11 c food3 100 1 5 c food2 10 2 4 c food1 1 3 7 d medicine1 100 1 SELECT item_id, genre_id, item_name, quantity FROM ( SELECT *, rank() over (PARTITION BY genre_id ORDER BY quantity DESC) as rank FROM test_item_order_data ) io WHERE io.rank < 3; 3 a book2 1000 1 a book1 100 6 b fashion2 100 9 b fashion4 10 2 b fashion1 10 11 c food3 100 5 c food2 10 7 d medicine1 100 |