gcpug / nouhau

Google Cloud Platformのノウハウを共有するRepository
https://gcpug.jp
MIT License
653 stars 23 forks source link

BigQueryでRECORDフィールドのうち特定のフィールドのみ変更するSQLの書き方 #91

Open orfeon opened 5 years ago

orfeon commented 5 years ago

WHAT

BigQueryでRECORDフィールドの中の一部を最小限の記述で置き換え・削除できるSQLの書き方。

WHY

Google AnalyticsやStackDriver loggigのexportテーブルなどで、ネストされたフィールド(RECORDフィールド)のうち一部だけを置き換えたり削除して新しいテーブルを作りたい場合がある。

だが現状、入れ子となるレコードの一部フィールドだけを直接書き換えるSQLは作れないため、該当RECORDフィールドを外してSTRUCTで作り直すSQLを作る必要がある。 (例: SELECT * EXCEPT(record), STRUCT(f1, f2, f3 + 1 AS f3) AS record FROM xxx.xxx)

RECORDフィールドが大量の子フィールドを持っていた場合、STRUCT内部で並べるフィールドが多すぎてSQLの保守性が悪化する。 (例: SELECT * EXCEPT(record), STRUCT(f1, f2, f3, f4,,,,,, f100 + 1 AS f100) AS record FROM xxx.xxx)

大量の子フィールドをもつRECORDでも一部置き換えをシンプルな記述で書く方法が知りたい。

orfeon commented 5 years ago

SELECT * EXCEPT(field), field 構文を使えば簡単にフィールドを一部だけ切り出すことができる。 STRUCT生成はSELECT AS STRUCT *という構文で作ることができる。 そこで(やや強引に)フィールドからサブクエリを作って以下のようにSTRUCT生成関数で置き換えを行うことができる。

SELECT * except(record),
(
  SELECT
    AS STRUCT * EXCEPT(f100),
    f100 + 1 AS f100
  FROM
    UNNEST([record])) AS record
FROM xxx.xxx