データ分析入門者のためのBigQuery50本ノック(初級編)

:::note info
この記事はLITALICO Advent Calendar 2022のカレンダー2の3日目の記事です。
https://qiita.com/advent-calendar/2022/litalico
:::

# はじめに

## 自己紹介

株式会社LITALICOでWEBエンジニアをやっています。ti-aiutoと申します。

普段は個人向けのWEBサービスの開発を担当していて、特にモノリスなアプリケーションを持続可能な形に保つこと、フロントエンドの開発しやすい環境を整えることに関心があります。

サービスの開発に加えて、なんだかんだでダッシュボードの構築やデータマート構築のような業務を担当することも多いです。ということで、今回はそんな中で学んだBigQueryの知識を人に伝えるという観点で、50本ノックと題して問題集を作ってみることにしました。

ちなみに今年は業務時間も使ってGoogleの研修プログラムを受講させてもらい、Google Cloud Professional Data Engineerという資格を取ってみたりもしました。今後はデータモデリングやデータウェアハウス構築の方向にも知見を深めていきたいなと思っています。（勝手にデータエンジニア見習いを名乗っている

## こんな方におすすめ

基本的には簡単なクエリを書いてデータ分析をしたり、データ分析をするための元データを取得したりしたい方に向けて書いています。
中でも、

* SQLの基本的な知識は本で読んだけど、実際に自分の手でクエリを書いたことはない
* 他のDBMS向けのクエリは書けるけど、BigQuery上で書いたことはない

という方におすすめしたいです。

## 使い方

普通に問題集として問題を解いてもよし、回答例を眺めるだけでもよし、写経してから後日解き直すでもよし、辞書代わりに使ってもよしです。
問題の後にヒントのリンクも張ってあるのでご活用ください。

## 構成

全体は初級編・中級編・実践編に分かれています。

初級編は、「SQL初心者が本で読んだことを試してみる」「SQLの本には書いてないけどBigQueryを使う上で特に必要な知識をつける」という観点で作りました。
中級編は、データ型やスキーマを意識するような問題を取り上げたのと、その他知っておくと便利な関数や演算子を使ってみる問題、またデータの簡単な前処理の手順にも触れています。
実践編は、「こんなクエリが書ければ書きたいと思ったクエリの大半は書けるはず」という観点で、独断と偏見の上で作った問題です。

拙い問題かもしれないですが多少は役に立つと思いますので、50問、お付き合いいただければ幸いです。

https://qiita.com/ti_aiuto/items/ceb08dddd91ff5d8f682

https://qiita.com/ti_aiuto/items/fbb1b655b89f41e777fc

## 問題で使うテーブルについて

今回は、基本情報技術者のテキストやSQLの解説書でもよく目にする（気がする）、簡単なECサイトの注文データとアクセスログを題材にしてみました。
なお消費税とか送料とか割引とか色違いとか難しいことは忘れることにします。

BigQuery上では `aiuto-public.knock2022_simple_ec` のデータセット内に格納してあります。

### 注文データ

* `items` 商品
    * `id(INT64)` 商品ID
    * `name(STRING)` 商品名
    * `price(INT64)` 価格
    * `stock(INT64)` 在庫数
* `users` 会員
    * `id(INT64)` 会員ID
    * `registered_at(TIMESTAMP)` 仮登録完了日時 
    * `confirmed_at(TIMESTAMP)` 本登録完了日時
* `orders` 注文
    * `id(INT64)` 注文ID
    * `user_id(INT64)` 会員ID(外部キー)
    * `ordered_at(TIMESTAMP)` 注文日時
    * `total(INT64)` 合計額
* `order_statements` 注文明細行(一回の注文での各商品の注文個数)
    * `order_id(INT64)` 注文ID(外部キー)
    * `item_id(INT64)` 商品ID(外部キー)
    * `quantity(INT64)` 個数
    * ※一つの注文IDについて、同じ商品IDの行は2行以上存在しない

### アクセスログ

* `access_log_transform_日付` テーブル
    * `time(TIMESTAMP)` アクセス日時
    * `date_jst(DATE)` アクセス日(日本時間)
    * `path(STRING)` HTTPリクエストのパス
    * `method(STRING)` HTTPリクエストのメソッド
    * `status_code(STRING)` HTTPレスポンスのステータスコード
    * `request_id(STRING)` リクエストに一意のID
    * `user_id(INT64)` 会員ID
* `access_log_raw_日付` テーブル
    * `time(INT64)` アクセス日時(UNIXTIME)
    * `message(STRING)` JSON形式でのログ情報

以下のGitHubリポジトリから、元データのCSVと、データの生成に使ったRubyのコードがダウンロードできます。

https://github.com/ti-aiuto/knock2022

# 初級編

## 問題

### ここから使うテーブル

`aiuto-public.knock2022_simple_ec.users` 会員テーブル

|id<br>会員id|registered_at<br>仮登録完了日時|confirmed_at<br> 本登録完了日時|
|:----|:----|:----|
|200477|2022-10-17 23:09:22 UTC|2022-10-23 23:57:24 UTC|
|...|...|...|

`aiuto-public.knock2022_simple_ec.items` 商品テーブル

|id<br>商品id|name<br>商品名|price<br>価格|stock<br>在庫数|
|:----|:----|:----|:----|
|1|ベーコン|299|12|
|...|...|...|...|

`aiuto-public.knock2022_simple_ec.orders` 注文テーブル

|id<br>注文id|user_id<br>会員ID|ordered_at<br>注文日時|total<br>合計額|
|:----|:----|:----|:----|
|5001|200001|2022-10-03 15:58:12 UTC|1984|
|...|...|...|...|

`aiuto-public.knock2022_simple_ec.order_statements` 注文明細行テーブル

|order_id<br>注文id|item_id<br>商品ID|quantity<br>個数|
|:----|:----|:----|
|5002|10001|1|
|...|...|...|

### 例題

`商品` テーブルから全ての行を取得して、 `商品名` と `価格` の列だけを抜き出してください。

|name|price|
|:----|:----|
|ベーコン|299|
|...|...|

#### 回答例

```SQL
SELECT
  name,
  price
FROM
  `aiuto-public.knock2022_simple_ec.items`
```

### 1. [SELECT] 行の絞り込み
`商品` テーブルから全ての列を取得して、 `価格` が100円以下の商品だけに絞り込んでください。

|id|name|price|stock|
|:----|:----|:----|:----|
|...|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#where_clause)

### 2. [SELECT] 行の並び替え

`商品` テーブルから全ての行と列を取得して、 `価格` が高い順に並び替えてください。

|id|name|price|stock|
|:----|:----|:----|:----|
|...|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#order_by_clause)

### 3. [演算子] 「...から...まで」の指定

`商品` テーブルから全ての列を取得して、 `価格` が100円以上999円以下の商品だけに絞り込んでください。
絞り込みには `BETWEEN` 演算子を活用してみてください。

|id|name|price|stock|
|:----|:----|:----|:----|
|...|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=ja#comparison_operators)

### 4. [SELECT] 行の重複を除く

`注文` テーブルから `会員ID` 列を取得して、重複を除いた `会員ID` の一覧を出力してください。

|user_id|
|:----|
|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#select_distinct)

### 5. [演算子] NULLを除く

`会員` テーブルから全ての列を取得して、 `本登録完了日時` が `NULL` ではない行（つまり、本登録完了している会員）だけに絞り込んでください。

|id|registered_at|confirmed_at|
|:----|:----|:----|
|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=ja#is_operators)

### 6. [集計] 列ごとの合計

`注文` テーブルを使って、 `会員ID` ごとに全注文の `合計額` の合計を計算してください。
`会員ID` ごとの全注文の合計額の列には、 `total_sum_by_user` という名前をつけてください。

|user_id|total_sum_by_user|
|:----|:----|
|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions?hl=ja#sum)

### 7. [集計] 集計値を使った絞り込み・並び替え

(6)の結果について、 `会員ID` ごとの合計額が30000(円)以上のものに限定して、合計額が多い順に並び替えてください。

|user_id|total_sum_by_user|
|:----|:----|
|200010|55682|
|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#having_clause)

### 8. [結合] 内部結合をしてから全ての列を取得

`注文明細行` テーブルの全ての行を取得して、 `注文明細行` テーブルの `商品ID` 列と `商品` テーブルの `商品ID` 列を突き合わせて内部結合を行い、2つのテーブルのすべての列を取得してください。

|order_id|item_id|quantity|id|name|price|stock|
|:----|:----|:----|:----|:----|:----|:----|
|...|...|...|...|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#inner_join)

### 9. [結合] テーブル名のエイリアスの活用・一部の列を取得

(8)の結果について、 `商品名` ・ `価格` ・ `数量` の列だけを取得してください。
結合条件の指定の際には、テーブル名のエイリアスを活用してみてください。

|name|price|quantity|
|:----|:----|:----|
|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#explicit_alias_syntax)

### 10. [SELECT] 列同士の演算

(9)の結果について、 `価格x数量` を計算して、商品ごとの注文合計額の列も一緒に出力してください。
商品ごとの注文合計額の列には `line_total` という名前をつけてください。

|name|price|quantity|line_total|
|:----|:----|:----|:----|
|...|...|...|...|


### 11. [結合] 複数のテーブルの結合

(9)の結果について、さらに `注文明細行` テーブルの `注文ID` 列と `注文` テーブルの `注文ID` 列を使って注文テーブルを結合し、 `注文日時` ・ `商品名` ・ `価格` ・ `数量` を取得してください。

|ordered_at|name|price|quantity|
|:----|:----|:----|:----|
|...|...|...|...|

### 12. [集計] 行数をカウントする

`注文明細行` テーブルを使って `商品ID` ごとの注文明細行の行数（つまり注文回数）を集計し、注文回数が多い順に並び替えてください。
注文回数の列には `orders_count_by_item` の名前をつけてください。


|item_id|orders_count_by_item|
|:----|:----|
|10001|869|
|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions?hl=ja#count)

### 13. [集計] 特定の列について重複を除いてカウントする

`注文明細行` テーブルと `注文` テーブルを結合して、 `商品ID` ごとの重複を除いた `会員ID` の件数（つまり注文した会員数）を集計し、会員数が多い順に並び替えてください。
会員数の列には `orders_count_by_item_by_unique_user` の名前をつけてください。

|item_id|orders_count_by_item_by_unique_user|
|:----|:----|
|10007|334|
|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions?hl=ja#count)

### 14. [集計] カウントの際のNULLの扱い

`会員` テーブルについて、 `仮登録完了日時` が `NULL` になっていない行数（つまり仮登録完了した人数）と、 `本登録完了日時` が `NULL` になっていない行数（つまり本登録完了した人数）を集計してください。
仮登録完了した人数には `registered_count` 、本登録完了した人数には `confirmed_count` という名前をつけてください。

|registered_count|confirmed_count|
|:----|:----|
|500|418|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions?hl=ja#count)

### ここから使うテーブル

ここからはアクセスログを題材にします。

どちらも日付で分割しているため、テーブル名に取得したい日付を指定する必要があります。
（例：10月22日のログを取得したければ `access_log_transform_20221022` とする）

`aiuto-public.knock2022_simple_ec.access_log_transform_日付` 整形済みアクセスログテーブル 

|time<br>アクセス日時|date_jst<br>アクセス日|path<br>HTTPリクエストのパス|method<br>HTTPリクエストのメソッド|status_code<br>HTTPレスポンスのステータスコード|request_id<br>リクエストに一意なID|user_id<br>会員ID|
|:----|:----|:----|:----|:----|:----|:----|
|2022-11-10 22:56:00 UTC|2022-11-11|/ranking|GET|200|6924bb32-f1cd-4f7a-a585-4446a8f62d82|200004|
|...|...|...|...|...|...|...|


### 15. [日付分割] 全ての日付のテーブルをクエリ

`整形済みアクセスログ` テーブルについて、全ての日付を対象として、全体の行数をカウントしてください。
カウントの列には `records_count` の名前をつけてください。

|records_count|
|:----|
|28826|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/wildcard-table-reference#wildcard_table_syntax)

### 16. [日付分割] 特定の日付のテーブルをクエリ

`整形済みアクセスログ` テーブルについて、2022年10月22日のテーブルだけを対象として、全体の行数をカウントしてください。
カウントの列には `records_count` の名前をつけてください。

|records_count|
|:----|
|805|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/wildcard-table-reference#wildcard_table_syntax)

### 17. [日付分割] 日付を範囲指定してクエリ

`整形済みアクセスログ` テーブルについて、2022年10月10日から2022年10月16日のテーブルだけを対象として、全体の行数をカウントしてください。
カウントの列には `records_count` の名前をつけてください。

|records_count|
|:----|
|10994|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/wildcard-table-reference#wildcard_table_syntax)

### 18. [正規表現] 正規表現を使って絞り込む

`整形済みアクセスログ` テーブルの2022年10月10日分について、正規表現を使って `パス` 列が `/items/商品ID` （ `商品ID` は0-9の1回以上の繰り返し）になっている行だけに絞り込み、全体の行数をカウントしてください。
カウントの列には `items_access_count` の名前をつけてください。

|items_access_count|
|:----|
|543|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions?hl=ja#regexp_contains)

「正規表現」になじみがない方はスキップしていただいても大丈夫です。
（簡単に言うと、専用の文法を使って「 `^[0-9]{3}-[0-9]{4}$`　数字3桁で始まって、その後にハイフンが続いて、さらに数字4桁が続いて終わる」のように文字の並びのパターンを表現できる方法です。）

https://www.tohoho-web.com/ex/regexp.html

### 19. [正規表現] 正規表現を使って値を抽出する

`整形済みアクセスログ` テーブルの2022年10月10日分について `アクセス日時` と `パス` の列を取得し、(18)と同様に商品ページへのアクセスに絞り込んだ上で、正規表現を使って `パス` の商品ID部分を抽出した列を加えてください。
商品IDの列の名前は `item_id` としてください。

|time|path|item_id|
|:----|:----|:----|
|...|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions?hl=ja#regexp_extract)

### 20. [演算子] LIKE検索

整形済みアクセスログテーブルの2022年10月10日分について `アクセス日時` と `パ` スの列を取得し、LIKE検索を使って `パス` が `/items/` から始まっている行に絞り込んでください。

|time|path|
|:----|:----|
|...|...|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=ja#comparison_operators)

### 21. [条件式] 条件により値を切り替える

`整形済みアクセスログ` テーブルの2022年10月10日分の全ての行について `アクセス日時` と `パス` の列を取得し、さらに `login_status` という名前でログイン状態を示す列を追加してください。
`login_status` 列は、その行の `会員ID` 列が `NULL` であれば `未ログイン` 、そうでなければ `ログイン済み` の値になるものとします。

|time|path|login_status|
|:----|:----|:----|
|...|...|未ログイン|
|...|...|ログイン済み|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/conditional_expressions?hl=ja#if)

### 22. [タイムスタンプ] タイムゾーンを考慮してタイムスタンプを文字列に変換する

`整形済みアクセスログ` テーブルの2022年10月10日分の全ての行について `アクセス日時` と `パス` の列を取得し、さらに `アクセス日時` を日本時間・日本語表記にした列を追加してください。
日本時間・日本語表記のアクセス日時の列は `time_jst_jpn` の名前をつけて、形式は `20xx年xx月xx日 xx時xx分xx秒` とします。

|time|path|time_jst_jpn|
|:----|:----|:----|
|...|...|2022年10月10日 03時14分57秒|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types?hl=ja#timestamp_type)
[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions?hl=ja#format_timestamp)
[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements?hl=ja#format_elements_date_time)

### 23. [タイムスタンプ] タイムゾーンを考慮してタイムスタンプと文字列を比較する

`整形済みアクセスログ` テーブルの2022年10月10日分について `アクセス日時` と `パス` の列を取得し、アクセス日時が2022年10月10日 19時以降のものだけに絞り込み、該当する行数をカウントしてください。
カウントの列には `after_1900_records_count` の名前をつけてください。

|after_1900_records_count|
|:----|
|368|

[ヒント](https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions?hl=ja#timestamp)

## 回答例

### 1. [SELECT] 行の絞り込み

```SQL
SELECT
  *
FROM
  `aiuto-public.knock2022_simple_ec.items`
WHERE
  price <= 100
```

### 2. [SELECT] 行の並び替え

```SQL
SELECT
  *
FROM
  `aiuto-public.knock2022_simple_ec.items`
ORDER BY
  price DESC
```


### 3. [演算子] 「...から...まで」の指定

```SQL
SELECT
  *
FROM
  `aiuto-public.knock2022_simple_ec.items`
WHERE
  price BETWEEN 100
  AND 999
```


### 4. [SELECT] 行の重複を除く

```SQL
SELECT
  DISTINCT user_id
FROM
  `aiuto-public.knock2022_simple_ec.orders`
```

### 5. [演算子] NULLを除く

```SQL
SELECT
  *
FROM
  `aiuto-public.knock2022_simple_ec.users`
WHERE
  confirmed_at IS NOT NULL
```
### 6. [集計] 列ごとの合計

```SQL
SELECT
  user_id,
  SUM(total) total_sum_by_user
FROM
  `aiuto-public.knock2022_simple_ec.orders`
GROUP BY
  user_id
```

### 7. [集計] 列ごとの合計を使った絞り込み・並び替え

```SQL
SELECT
  user_id,
  SUM(total) total_sum_by_user
FROM
  `aiuto-public.knock2022_simple_ec.orders`
GROUP BY
  user_id
HAVING
  total_sum_by_user >= 30000
ORDER BY
  total_sum_by_user DESC
```

### 8. [結合] 内部結合をしてから全ての列を取得

```SQL
SELECT
  *
FROM
  `aiuto-public.knock2022_simple_ec.order_statements`
JOIN
  `aiuto-public.knock2022_simple_ec.items`
ON
  `aiuto-public.knock2022_simple_ec.order_statements`.item_id = `aiuto-public.knock2022_simple_ec.items`.id
```

### 9. [結合] テーブル名のエイリアスの活用・一部の列を取得

```SQL
SELECT
  items.name,
  items.price,
  order_statements.quantity
FROM
  `aiuto-public.knock2022_simple_ec.order_statements` order_statements
JOIN
  `aiuto-public.knock2022_simple_ec.items` items
ON
  order_statements.item_id = items.id
```

### 10. [SELECT] 列同士の演算

```SQL
SELECT
  items.name,
  items.price,
  order_statements.quantity,
  items.price * order_statements.quantity line_total
FROM
  `aiuto-public.knock2022_simple_ec.order_statements` order_statements
JOIN
  `aiuto-public.knock2022_simple_ec.items` items
ON
  order_statements.item_id = items.id
```

### 11. [結合] 複数のテーブルの結合

```SQL
SELECT
  orders.ordered_at,
  items.name,
  items.price,
  order_statements.quantity
FROM
  `aiuto-public.knock2022_simple_ec.order_statements` order_statements
JOIN
  `aiuto-public.knock2022_simple_ec.items` items
ON
  order_statements.item_id = items.id
JOIN
  `aiuto-public.knock2022_simple_ec.orders` orders
ON
  order_statements.order_id = orders.id
```

### 12. [集計] 行数をカウントする

```SQL
SELECT
  item_id,
  COUNT(*) orders_count_by_item
FROM
  `aiuto-public.knock2022_simple_ec.order_statements`
GROUP BY
  item_id
ORDER BY
  orders_count_by_item DESC
```

### 13. [集計] 特定の列について重複を除いてカウントする

```SQL
SELECT
  item_id,
  COUNT(DISTINCT user_id) orders_count_by_item_by_unique_user
FROM
  `aiuto-public.knock2022_simple_ec.order_statements` order_statements
JOIN
  `aiuto-public.knock2022_simple_ec.orders` orders
ON
  order_statements.order_id = orders.id
GROUP BY
  item_id
ORDER BY
  orders_count_by_item_by_unique_user DESC
```

### 14. [集計] カウントの際のNULLの扱い

```SQL
SELECT
  COUNT(registered_at) registered_count,
  COUNT(confirmed_at) confirmed_count
FROM
  `aiuto-public.knock2022_simple_ec.users`
```

### 15. [日付分割] 全ての日付のテーブルをクエリ

```SQL
SELECT
  COUNT(*) records_count
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_*`
```

### 16. [日付分割] 特定の日付のテーブルをクエリ

```SQL
SELECT
  COUNT(*) records_count
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221022`
```

### 17. [日付分割] 日付を範囲指定してクエリ

```SQL
SELECT
  COUNT(*) records_count
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_*`
WHERE
  _TABLE_SUFFIX BETWEEN '20221010'
  AND '20221016'
```

### 18. [正規表現] 正規表現を使って絞り込む

```SQL
SELECT
  COUNT(*) items_access_count
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221010`
WHERE
  REGEXP_CONTAINS(path, "/items/[0-9]+$")
```

### 19. [正規表現] 正規表現を使って値を抽出する

```SQL
SELECT
  time,
  path,
  REGEXP_EXTRACT(path, "/items/([0-9]+)$") item_id
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221010`
WHERE
  REGEXP_CONTAINS(path, "/items/[0-9]+$")
```

### 20. [演算子] LIKE検索

```SQL
SELECT
  time,
  path
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221010`
WHERE
  path LIKE "/items/%"
```

### 21. [条件式] 条件により値を切り替える

```SQL
SELECT
  time,
  path,
IF
  (user_id IS NULL, "未ログイン", "ログイン済み") login_status
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221010`
```

### 22. [タイムスタンプ] タイムゾーンを考慮してタイムスタンプを文字列に変換する

```SQL
SELECT
  time,
  path,
  FORMAT_TIMESTAMP('%Y年%m月%d日 %H時%M分%S秒', time, 'Asia/Tokyo') time_jst_jpn
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221010`
```

### 23. [タイムスタンプ] タイムゾーンを考慮してタイムスタンプと文字列を比較する

ポイント：条件は9時間引いて（UTCのタイムゾーンで） `time >= "2022-10-10 10:00:00"` と書くこともできますが、可読性がよろしくないため `TIMESTAMP(日本時間の表記, "Asia/Tokyo")` とするのが便利です。

```SQL
SELECT
  COUNT(*) after_1900_records_count
FROM
  `aiuto-public.knock2022_simple_ec.access_log_transform_20221010`
WHERE
  time >= TIMESTAMP("2022-10-10 19:00:00", "Asia/Tokyo")
```

# 中級編へ続く

明日も私 @ti_aiuto が執筆を担当させていただきます。次回はより幅広く概念を覚えていくのと、頭は少し疲れるけれど便利なテクニックをご紹介していきたいと思います。

https://qiita.com/ti_aiuto/items/ceb08dddd91ff5d8f682