Athena にて EXPRESSION_NOT_CONSTANT エラーが発生
発生した問題
Athena マネジメントコンソールにてSQLを組み立てていたところ、以下のエラーが発生した。
EXPRESSION_NOT_CONSTANT: line xxx: Constant expression cannot contain column references
原因
定数を指定すべき箇所で、テーブルの予約キーワードを指定していた。
より具体的には、SQL内で文字列リテラルを指定したい箇所にて、シングルクォートではなくダブルクォートを使用したことが原因。
-- EXECUTE は、パラメータ化されたクエリを実行するためのキーワード
-- 詳細 : https://docs.aws.amazon.com/ja_jp/athena/latest/ug/querying-with-prepared-statements.html
EXECUTE extract_mytable using "column1";
解決策
文字列リテラルを指定する場合、シングルクォートを使用する。
EXECUTE extract_mytable using 'column1';
ただし、「列名」など、テーブルに関するメタデータを指定する場合は、ダブルクォートを使用する。
select "column1", count(1) from my_table group by "column1";
ただし、Athena prepared statement を使用して、列指定部分 (group by
や order by
など)を EXECUTE
で後から指定しようとするとうまくいかない(その他の問題に記載)。
そもそも prepared statement は、2024年6月現在だと where でしか利用できない。
現在、? パラメータは WHERE 句にのみ配置できます。SELECT ? FROM table のような構文はサポートされていません。
引用元 https://docs.aws.amazon.com/ja_jp/athena/latest/ug/querying-with-prepared-statements.html
列指定するようなステートメント( group by
や order by
)には、そもそも使用できなかった。
エラーの詳細
Athena では、ダブルクォートは、「Athenaの予約語をエスケープするための記号」という意味を持つ。
SQL の SELECT ステートメントや ビュー のクエリで予約キーワードをエスケープするには、二重引用符 ('') で囲みます。
引用元 : https://docs.aws.amazon.com/ja_jp/athena/latest/ug/reserved-words.html
文字列リテラルはシングルクォート、SQLクエリの予約語(列名など)はダブルクォートで囲む。
シングルクォート・ダブルクォートを間違えると、エラーをはじめとした意図しない挙動に見舞われる。
意図しない挙動の例
例えば、以下のようなテーブルがあったとする。
select * from worker;
id | name | department |
---|---|---|
34567 | saburo | 開発 |
12345 | taro | 営業 |
45678 | goro | 品質 |
34568 | shiro | 開発 |
23456 | jiro | 営業 |
このデータを、 department
列で集計したいとする。
この時、 department
を ダブルクォートでくくるか、シングルクォートでくくるかで、結果が変化する。
◆ ダブルクォートでくくる(意図した挙動)
select "department", count(*) as department_count from worker group by "department";
department | department_count |
---|---|
品質 | 1 |
開発 | 2 |
営業 | 2 |
◆ シングルクォートでくくる(意図しない挙動)
エラー扱いされずに動いてしまう。
select 'department', count(*) as department_count from worker group by 'department';
_col0 | department_count |
---|---|
department | 5 |
恐らく、"列名"ではなく、謎の文字列を指定した扱い。
group by Null
等と同じ挙動。
この時、列名をダブルクォートでくくる(or なにもくくらない)と、エラーが発生する。
select department, count(*) as department_count from worker group by 'department';
EXPRESSION_NOT_AGGREGATE: line 1:8: 'department' must be an aggregate expression or appear in GROUP BY clause
その他の問題
using
で うまく列名指定出来ない
「Prepared Statement」の Athenaの Prepared Statement 機能を使って、 group by
など列名部分を後から挿入することを考える。
エラーの詳細 にある通り、 group by
など、列名を指定する時はダブルクォートでくくる必要がある。
しかし、ダブルクォートで列名を指定すると、本記事冒頭のエラーが発生する。
EXPRESSION_NOT_CONSTANT: line xxx: Constant expression cannot contain column references
恐らく、Prepared Statement の性質上どうしようもないと思われる。
(自分が知らないだけで、解決方法があるかも?)
最後に
たまにハマるので注意。
Discussion