
BigQueryで集計クエリを書く際、「GROUP BYでまとめたけれど、まとめていない他のカラムも一緒に取得したい」というケースはたまに発生する。
しかし、SQLのルール上、グループ化していない列をそのままSELECT句に書くとエラーになってしまう。
そんな時に役立つのがANY_VALUE関数である。
本記事では、ANY_VALUE関数の意味や使い方、どのような場面で使うと便利なのかを、なるべくわかりやすく解説する。
ANY_VALUE関数とは何か
BigQueryのANY_VALUE関数とは、集計クエリなどで「どの値でもよい」列の値を1つ返したいときに使う集計関数である。
通常、GROUP BY句でグルーピングして集計するとき、グループ化していない列をそのままSELECT句に書くと下記のようなエラーとなる。
しかし「このカラムはどの値でも良いので、とにかく1つ欲しい」という場合、ANY_VALUE関数を使うことでエラーを回避し、クエリをシンプルにすることができる。
ANY_VALUEは、指定した列の値のうち、グループごとに任意の1つの値を返す。
例えば、A列に対してANY_VALUEを指定すると、A列にある値(1,2,3,4,5)の内、どれかをランダムに返してくれる。
最初に実行した時は 1 を返したが、次実行したら、5を返す 、というような感じだ。
どの値が返るかは保証されないため、値に意味がある場合や正確性が必要な場合は使わない方がいい。
そのため、本番データで利用することはそこまで多くないが、個人的には、サンプルデータを作ったり、テストデータを作成する時にランダムな値を返してくれるので、結構便利だなという印象を受けている。
このように、ANY_VALUEは、SQLの集計処理でありがちな「値をひとつだけ表示したいが、どの値でもいい」「テストデータ作りたい」という場面で役立つ関数である。
ANY_VALUE関数の基本的な使い方
ANY_VALUE関数の基本的な構文は以下の通りである。
1 2 3 4 5 6 7 8 | SELECT 列A ,ANY_VALUE(列B) AS 任意の値 FROM テーブル名 GROUP BY 列A |
例えば、従業員テーブル(employees)で部署ごとに従業員数と部署名を集計したいが、部署名(department_name)はどの値でもよい場合、次のようなSQLを書くことができる。
1 2 3 4 5 6 7 8 9 | SELECT department_id ,COUNT(*) AS employee_count ,ANY_VALUE(department_name) AS department_name FROM employees GROUP BY department_id |
このようにANY_VALUEを使うと、エラーを出さずに、GROUP BY対象外の列を簡単に取得できるため、わざわざサブクエリやJOINを使わずに済む。
ANY_VALUEを使う目的とメリット
ANY_VALUE関数を使う主な目的は、集計時のエラー回避とSQLの簡素化である。
通常、GROUP BYでグループ化した場合、グループ化していない列はSELECTで使えないため、COUNTやSUMなどの集約関数で包む必要がある。
ANY_VALUEは「どの値でもいい」という前提で、その列の値をひとつだけ返してくれるため、複雑なクエリを書く必要がなくなる。
【主なメリット】
GROUP BY時のエラーを回避できる
SELECT句にGROUP BY対象外の列を書くとエラーになるが、ANY_VALUEで包むことでエラーにならず値を取得できる。- サンプルデータを作りたい時に便利
指定した列の値からバラバラの組み合わせのテストデータを作りたい、という時にランダムに値を返す特性が利用できる。 SQLを簡単に書ける
サブクエリやウィンドウ関数を使う必要がないため、クエリが短く、シンプルになる。クエリのパフォーマンス向上
余分なJOINやサブクエリを減らすことで、クエリの実行速度が上がる場合がある。
ただし、ANY_VALUEは返す値を保証しないため、「どの値でもよい」ケース以外では安易に使わないことが大切である。
まとめ
ANY_VALUE関数は、BigQueryでの集計やデータ分析時に「どの値でもよい」列を簡単に1つだけ取得したい場合に使える便利な関数である。
GROUP BY句と併用することで、エラー回避やクエリの簡素化、パフォーマンス向上など多くのメリットがある。
しかし、どの値が返るかは保証されないため、重要なデータや一意な値が必要な場面では注意して利用することが重要だ。