Legoliss Blog

Legoliss’s blog

CDP、Salesforce Marketing Cloudについて書いてます。

AthenaにはOFFSET句がないので、ウィンドウ関数でなんとかする

AWS Athenaは最近コンソール画面も刷新され、さらに手軽に使いやすくなりましたね。

ところで、AthenaはクエリエンジンのベースにPrestoを採用しています。 そのため、私のようなRDBMS慣れした無精者は時々思わぬところで思わぬエラーに遭遇することになるのです。

AWS Athena
AWS Athena

Athena(Presto)にはOFFSETが無い

SELECTのクエリ結果をページングしようと思って、何の気無しに下記のようなSQLを投げると、(当たり前ですが)エラーになります。

SELECT * 
FROM "database"."table"
ORDER BY work_date ASC
LIMIT 10
OFFSET 10

Mismatched input OFFSET
Mismatched input OFFSET
work_dateの昇順で、1ページあたり10件の2ページ目がほしいんですが、「'OFFSET'?ナニソレ??」って言われます。

RDB慣れしてると、まさかこんな簡単なSQLでエラーが返るなんて思ってないので、一瞬パニクるわけですが、落ち着きましょう。AthenaはPrestoです。OFFSET句は存在しないため、エラーになって当たり前。


ウィンドウ関数とLIMIT句を組み合わせて、OFFSETと同じ動作を実現する

じゃあAthenaでクエリ結果をページングしたいときはどうすんのさ。っていうことですが、Prestoのウィンドウ関数とLIMIT句の組み合わせで実現できます。

SELECT * 
FROM (
  SELECT 
    row_number() OVER (ORDER BY work_date) AS rownum, 
    * 
  FROM "database"."table"
) AS base_table
WHERE rownum > 10
LIMIT 10;

row_number() がウィンドウ関数で、各行に1から始まるシーケンシャルな数値を付与します。 OVER句でウィンドウ関数が適用されるウィンドウを定義します。

work_date昇順で行番号を付与し、行番号が10より大きいレコードを10件取得しています。

work_dateの昇順で、1ページあたり10件の2ページ目

と、結果は同じになるはずです。


まとめ

思い込みと拙速はエラーのもとですね。(自戒)


参照

以下、参考にさせていただきました。 お礼申し上げます。