Google Big Query レガシーSQLの構文でハマったこと
こんにちは、kisseです。
今日は、Google Big QueryのレガシーSQLの構文についてのメモです。
現在は、標準SQLという方が推奨されているようですが、事情によりレガシーSQLを使う方は参考にしてください!
僕は、基本的にmysqlとBig Queryしか使ったことがないので、mysqlとの違いが焦点になります。
GROUP BY句において関数が使用できない
結構どハマりしました。
例えばmysqlだと、
SELECT some_func(column_a) AS column_a2, count(*) FROM some_table GROUP BY some_func(column_a)
このような書き方しますよね??
GROUP BY句にSELECT句で命名した名前を入れるとエラーが帰ってきます。
でもレガシーSQLだと上記のSQLではエラーが発生します。
レガシーSQLを使う場合には、以下のように記述してください。
SELECT some_func(column_a) AS columns_a2, count(*) FROM some_table GROUP BY column_a2
mysqlでは出来ない、SELECT句で命名した名前しかGROUP BY句では指定できず、関数を使うとエラー出ます。
これなかなか厄介で、サブクエリで1つだけカラムを指定した上でINで条件指定することが出来なくなったりします。
(もしかしたら他に方法があるかもしれないけど、単純には行かなさそうです。)
自然結合にはINNER JOINを使わなければいけない
mysqlでテーブルの自然結合するには、FROM句で2つのテーブルを指定してからWHERE句で結合カラムを指定します。
(もちろん、mysqlでもINNER JOINを用いた自然結合はできる。)
しかし、BigQueryではそのような形式での自然結合を行うことができません。(!?)
FROM句にテーブルを2つ記載すると、UNION ALLの意味になります(!?!?)
SELECT table1.*, table2.some_column, ... FROM table1, table2 WHERE table1.table2_id = table2.id
上記はmysqlでは動作しますが、Big Queryではエラーが帰ってきます。
SELECT table1.*, table2.some_column, ... FROM table1 INNER JOIN table2 ON table1.table2_id = table2.id
mysqlでもこのように書いた方が可読性は高い気がしますねー。
GROUP BYで特定の行を取り出すには
mysqlではGROUP BYでグループ化を行った後に特定のカラムに対してMAX()やMIN()を適用すると、その結果に対応したレコードが取得できます。
(公式のドキュメントを見ると、そのような記述が見つけられなくて不安になっているんですけど…。知っている方教えてください。)
Big Queryではそのような取得の方法はできません。
サブクエリで、MAX()なりMIN()なりの値を取り出したあとに、自己結合を行って条件指定するとそのようなレコードを取得することができました。
おわり
以上の3点でめちゃめちゃハマったので書きました。
これからBig Query初めて使うって方は標準SQLを使った方がいいと思います!
レガシーSQL使わなきゃいけないのでなければ、標準SQLの方が便利みたいです。
(実際僕も標準SQL使ってよかったらしいので、これからそっちにしようかと思ってるところです。)
最後まで読んでいただきありがとうございます!