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
その他の問題
「Prepared Statement」の using で うまく列名指定出来ない
Athenaの Prepared Statement 機能を使って、 group by など列名部分を後から挿入することを考える。
エラーの詳細 にある通り、 group by など、列名を指定する時はダブルクォートでくくる必要がある。
しかし、ダブルクォートで列名を指定すると、本記事冒頭のエラーが発生する。
EXPRESSION_NOT_CONSTANT: line xxx: Constant expression cannot contain column references
恐らく、Prepared Statement の性質上どうしようもないと思われる。
(自分が知らないだけで、解決方法があるかも?)
最後に
たまにハマるので注意。
Discussion