SlideShare une entreprise Scribd logo
1  sur  26
Télécharger pour lire hors ligne
BigQuery勉強会
~Standard SQL Dialect~
2016/8/23
森下健 @ Sprocket
1
今回の内容
• Standard SQLの基本
• Standard SQLの便利機能を紹介
• (user, action, time) というイベントデータの処理例
• 間隔ベースのセッションIDを付ける
• ユーザやセッションの属性とイベントデータを⼀つのテーブルにする
• あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計
2
Standard SQLの基本
3
Standard SQL Dialect
• 2016年6⽉にBeta公開された書き⽅
• ⼤規模かつ複雑な処理の記述が可能
• (以前のをよく知らないので差分はわからないんですが)
• BQは処理が複雑でも料⾦同じなのでかなり使いみちがある
• なぜ「Standard」なのかと⾔われてもわかりません...
https://cloud.google.com/blog/big-data/2016/06/bigquery-111-now-with-standard-sql-iam-and-partitioned-tables
4
Standard SQLモードに切り替えて使う
②チェックを外す
①Show Optionsで開いて
5
Time Partitioning
• _PARTITIONTIME というのがあるらしいが、よく知らない…
• https://cloud.google.com/bigquery/docs/partitioned-tables
• 今の旧来のテーブルならば
という形で取れます
SELECT ...
FROM `my_dataset.table_name_*`
WHERE _TABLE_SUFFIX BETWEEN '20160720' AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
①
②
6
細かいこと
• JSON_EXTRACT 関数が消えた
• DISTINCT がまともに動く感じになった
• /* ... */ でコメントになる
• 最後の結果セットをOrder Byできるサイズの上限は結構低い
• 数千万レコードでもNGだったりする
• ※ 完全ではないが対処法はある
• 昔はTipsとしてよく⾔われていた EACH とかもう不要
7
Standard SQLの便利機能 3つ
WITH
Analytic Function
Nest
8
WITH構⽂
SELECT ...
FROM (
SELECT ...
FROM (
SELECT ...
FROM original_data
) as A
) as B
WITH A as (
SELECT ...
FROM original_data
)
, B as (
SELECT ...
FROM A
)
SELECT ...
FROM B
■ 従来記法 ■ WITH記法
⼊れ⼦地獄から解放され、上から下に処理を書けるようになった 9
Analytic Function
• 以前の Window Function (今回呼び名変わった?)
• ※新しい機能ではないが紹介
• 普通のSQL(例えばMySQLの)ではできない、レコード間の演算
ができる
10
11
user action time
1 A 1
1 B 1
1 X 5
1 B 8
1 Z 9
2 A 2
2 B 5
2 D 10
例えば、ユーザ毎にアクセス順序でのSequence IDを付けたい
user action time seq
1 A 1 1
1 B 1 2
1 X 5 3
1 B 8 4
1 Z 9 5
2 A 2 1
2 B 5 2
2 D 10 3
SELECT *, RANK() OVER (PARTITION BY user ORDER BY time) as seq
FROM data
ORDER BY user, seq
RANK():
1から順に連番をふる
12
user action time
1 A 1
1 B 1
1 X 5
1 B 8
1 Z 9
2 A 2
2 B 5
2 D 10
例えば、ユーザ毎に前回アクセスからの経過時刻をとりたい
WITH add_last_time as (
SELECT *,
LAG(time) OVER (PARTITION BY user ORDER BY time) as last_time
FROM data
)
, add_span as (
SELECT *,
time - last_time as span
FROM add_last_time
)
select * from add_span ORDER BY user, time
user action time last_time span
1 A 1 null null
1 B 1 1 0
1 X 5 1 4
1 B 8 5 3
1 Z 9 8 1
2 A 2 null null
2 B 5 2 3
2 D 10 5 5
LAG(X):
⼀つ前のXの値を取得する
13
user action time
1 A 1
1 B 1
1 X 5
1 B 8
1 Z 9
2 A 2
2 B 5
2 D 10
例えば、ユーザ毎に最初の2つのデータを残したい
WITH add_seq as (
SELECT *, RANK() OVER (PARTITION BY user ORDER BY time) as seq
FROM data
)
, omit_records as (
SELECT * FROM add_seq WHERE seq <= 2
)
SELECT * FROM omit_records
ORDER BY user, seq
user action time seq
1 A 1 1
1 B 1 2
2 A 2 1
2 B 5 2
Nest (⼊れ⼦)
• これがかなり便利
• 普通のSQLには無い感覚なので慣れは必要だが慣れるとデータ
のこねくり回しが捗ります
• 保存・Scanデータ量の削減になる
• user_idのような⽂字列などの場合特に
14
15
例えば、Actionを⾏ったユーザをAction毎にまとめる(ユーザの重複OKの場合)
user action time
1 A 1
1 B 3
1 X 5
1 B 20
1 Z 22
2 A 2
2 B 30
2 X 60
3 X 4
4 B 2
4 A 4
Row action users
1 A 1
2
4
2 B 1
1
2
4
3 X 1
2
3
4 Z 1
重複しているよ?
WITH action_users as (
SELECT action, ARRAY_AGG(user) as users
FROM data
GROUP by action
)
SELECT * FROM action_users
ORDER BY action
ARRAY_AGG():
GROUP BYと共に使い、
値をARRAY型の1レコードにまとめる
16
例えば、Actionを⾏ったユーザをAction毎にまとめる(ユニークユーザの場合)
user action time
1 A 1
1 B 3
1 X 5
1 B 20
1 Z 22
2 A 2
2 B 30
2 X 60
3 X 4
4 B 2
4 A 4
WITH action_users as (
SELECT action, ARRAY_AGG(user) as users
FROM data
GROUP by action
)
, unique_action_users as (
SELECT action,
ARRAY(
SELECT DISTINCT user FROM UNNEST(users) as user
) as users
FROM action_users
)
SELECT * FROM unique_action_users ORDER BY action
Row action users
1 A 1
2
4
2 B 1
2
4
3 X 1
2
3
4 Z 1
ARRAY():
Sub Queryが単⼀列の複数(0~N)レコード
を返す場合に使う.
UNNEST():
ARRAY型を展開する。
JOIN的になる場合と
グループ単位で処理したい場合で
少し意味合いが違う感じ.
Row action users
1 A 1
2
4
2 B 1
1
2
4
3 X 1
2
3
4 Z 1
■Group By する必要がある場合: ARRAY_AGG(STRUCT(...)) ... GROUP BY
SELECT ...,
ARRAY_AGG(STRUCT(col1, col2, ...))
FROM ...
GROUP BY X
複数列をArray型に⼊れる⽅法
■Group By する必要がない場合 or 何か計算処理する場合: ARRAY(SELECT STRUCT(...))
SELECT ...,
ARRAY(
SELECT STRUCT(col1 * 2, SUM(col2) OVER ... , ...) FROM ...
)
FROM ... STRUCT():
レコード型を作る。
レコード型という単⼀列になる。
(user, action, time)
というイベントデータの処理例
18
19
間隔ベースのセッションIDを付ける
user action time
1 A 1
1 B 3
1 X 5
1 B 20
1 Z 22
2 A 2
2 B 30
2 X 35
やりたいこと: ユーザ毎にアクセス間隔が10以上なら別のSessionIDを付けるようにしたい
1
2
1
2
user action time last_time new_session session_seq
1 A 1 null 0 1
1 B 3 1 0 1
1 X 5 3 0 1
1 B 20 5 1 2
1 Z 22 20 0 2
2 A 2 null 0 1
2 B 30 2 1 2
2 X 35 30 0 2
WITH add_last_time as (
SELECT *,
LAG(time) OVER (PARTITION BY user ORDER BY time) as last_time
FROM data
)
, add_span as (
SELECT *, IF(time - last_time >= 10, 1, 0) as new_session
FROM add_last_time
)
SELECT *, 1+SUM(new_session) OVER (PARTITION BY user ORDER BY time) as session_seq
FROM add_span ORDER BY user, time
user session_seq session_start_time session_end_time session_time_span actions.action actions.time
1 1 1 5 4 A 1
B 3
X 5
1 2 20 22 2 B 20
Z 22
2 1 2 2 0 A 2
2 2 30 35 5 B 30
20
ユーザやセッションの属性とイベントデータを⼀つのテーブルにする: Step1
user action time
1 A 1
1 B 3
1 X 5
1 B 20
1 Z 22
2 A 2
2 B 30
2 X 35
やりたいこと:ユーザやセッションの属性とイベントデータを⼀つのテーブルにする
WITH ... 略 ...
, add_session_seq as (
SELECT *, 1+SUM(new_session) OVER (PARTITION BY user ORDER BY time) as session_seq
FROM add_span
)
SELECT user, session_seq,
MIN(time) as session_start_time,
MAX(time) as session_end_time,
MAX(time) - MIN(time) as session_time_span,
ARRAY_AGG(STRUCT(action, time)) as actions
FROM add_session_seq
GROUP BY user, session_seq
user session_seq ... actions.action actions.time
1 1 A 1
B 3
X 5
1 2 B 20
Z 22
2 1 A 2
2 2 B 30
21
ユーザやセッションの属性とイベントデータを⼀つのテーブルにする: Step2
やりたいこと:ユーザやセッションの属性とイベントデータを⼀つのテーブルにする
WITH ... 略 ...
, group_by_user as (
SELECT user,
MAX(session_seq) as session_num,
ARRAY_AGG(STRUCT(
session_start_time, session_end_time, session_time_span, actions
)) as sessions
FROM group_by_session GROUP BY user
)
SELECT * FROM group_by_user
ORDER BY user
user session_num sessions.session_start_time sessions.session_end_time sessions.session_time_span sessions.actions.action sessions.actions.time
1 2 1 5 4 A 1
B 3
X 5
20 22 2 B 20
Z 22
2 2 2 2 0 A 2
30 35 5 B 30
X 35
22
ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計
やりたいこと: Xの後に時刻10以内にZが発⽣する割合を求める
user action time
1 A 1
1 X 5
1 B 9
1 Z 11
2 A 2
2 X 15
2 Z 40
3 Z 3
3 X 6
4 X 4
4 X 5
4 Z 7
1
0 (時刻10以内でない)
0 (ZがXの後で発⽣していない)
1 (最初のXに対してのみ計算するとする)
X=4, Z=2 → 50% とカウントしたい
23
ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計
user action time
1 A 1
1 X 5
1 B 9
1 Z 11
2 A 2
2 X 15
2 Z 40
3 Z 3
3 X 6
4 X 4
4 X 5
4 Z 7
user first_x_time action_times.action action_times.time
1 5 X 5
Z 11
2 15 X 15
Z 40
3 6 Z 3
X 6
4 4 X 4
X 5
Z 7
WITH group_by_user as (
SELECT user, ARRAY_AGG(STRUCT(action, time)) as action_times
FROM data WHERE action in ('X', 'Z')
GROUP BY user
),
pickup_first_x_timeas (
SELECT user, action_times,
(
SELECT MIN(time)
FROM UNNEST(action_times) WHERE action='Xʼ
) as first_x_time
FROM group_by_user
)
SELECT * FROM pickup_first_x_time ORDER BY user
24
ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計
user first_x_time action_times.action action_times.time
1 5 X 5
Z 11
2 15 X 15
Z 40
3 6 Z 3
X 6
4 4 X 4
X 5
Z 7
WITH ...
, count_z as (
SELECT user, first_x_time,
(
SELECT COUNT(*)
FROM UNNEST(action_times) as a
WHERE a.action = 'Zʼ
AND a.time BETWEEN first_x_time AND first_x_time + 10
) as z_count,
action_times
FROM pickup_first_x_time
)
SELECT * FROM count_z ORDER BY user
user first_x_time z_count action_times.action action_times.time
1 5 1 X 5
Z 11
2 15 0 X 15
Z 40
3 6 0 Z 3
X 6
4 4 1 X 4
X 5
Z 7
25
WITH ...
SELECT
COUNT(*) as x_cnt,
COUNTIF(z_count > 0) as z_cnt
FROM count_z
user first_x_time z_count action_times.action action_times.time
1 5 1 X 5
Z 11
2 15 0 X 15
Z 40
3 6 0 Z 3
X 6
4 4 1 X 4
X 5
Z 7
ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計
x_cnt z_cnt
4 2
まとめ
• Standard SQLは結構強い
• まだβ版なので仕様が変わる可能性もあるが、考え⽅などは変
わらないので慣れておくのは良いこと
• 是⾮活⽤していきましょう!
26

Contenu connexe

Tendances

Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうRyuji Tsutsui
 
DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技Yoichi Toyota
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
Snowflake Architecture and Performance
Snowflake Architecture and PerformanceSnowflake Architecture and Performance
Snowflake Architecture and PerformanceMineaki Motohashi
 
OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...
OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...
OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...NTT DATA Technology & Innovation
 
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
ログ解析を支えるNoSQLの技術
ログ解析を支えるNoSQLの技術ログ解析を支えるNoSQLの技術
ログ解析を支えるNoSQLの技術Drecom Co., Ltd.
 
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築Junji Nishihara
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことAmazon Web Services Japan
 
A5 SQL Mk-2の便利な機能をお教えします
A5 SQL Mk-2の便利な機能をお教えしますA5 SQL Mk-2の便利な機能をお教えします
A5 SQL Mk-2の便利な機能をお教えしますester41
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
SQLおじさん(自称)がBigQueryのStandard SQLを使ってみた
SQLおじさん(自称)がBigQueryのStandard SQLを使ってみたSQLおじさん(自称)がBigQueryのStandard SQLを使ってみた
SQLおじさん(自称)がBigQueryのStandard SQLを使ってみたKumano Ryo
 
BigQuery Query Optimization クエリ高速化編
BigQuery Query Optimization クエリ高速化編BigQuery Query Optimization クエリ高速化編
BigQuery Query Optimization クエリ高速化編sutepoi
 
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまでLINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまでLINE Corporation
 
Kong Enterprise の紹介
Kong Enterprise の紹介Kong Enterprise の紹介
Kong Enterprise の紹介Yoshito Tabuchi
 
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニックinfinite_loop
 
[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda
[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda
[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi UmedaInsight Technology, Inc.
 

Tendances (20)

Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
Power Automateを使ってツヨツヨ情報収集ツールを作ろう
Power Automateを使ってツヨツヨ情報収集ツールを作ろうPower Automateを使ってツヨツヨ情報収集ツールを作ろう
Power Automateを使ってツヨツヨ情報収集ツールを作ろう
 
Snowflake Architecture and Performance
Snowflake Architecture and PerformanceSnowflake Architecture and Performance
Snowflake Architecture and Performance
 
nginx入門
nginx入門nginx入門
nginx入門
 
OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...
OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...
OSSプロジェクトへのコントリビューション はじめの一歩を踏み出そう!(Open Source Conference 2022 Online/Spring...
 
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
ログ解析を支えるNoSQLの技術
ログ解析を支えるNoSQLの技術ログ解析を支えるNoSQLの技術
ログ解析を支えるNoSQLの技術
 
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
"Kong Summit, Japan 2022" パートナーセッション:Kong on AWS で実現するスケーラブルな API 基盤の構築
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 
A5 SQL Mk-2の便利な機能をお教えします
A5 SQL Mk-2の便利な機能をお教えしますA5 SQL Mk-2の便利な機能をお教えします
A5 SQL Mk-2の便利な機能をお教えします
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
SQLおじさん(自称)がBigQueryのStandard SQLを使ってみた
SQLおじさん(自称)がBigQueryのStandard SQLを使ってみたSQLおじさん(自称)がBigQueryのStandard SQLを使ってみた
SQLおじさん(自称)がBigQueryのStandard SQLを使ってみた
 
BigQuery Query Optimization クエリ高速化編
BigQuery Query Optimization クエリ高速化編BigQuery Query Optimization クエリ高速化編
BigQuery Query Optimization クエリ高速化編
 
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまでLINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
 
Kong Enterprise の紹介
Kong Enterprise の紹介Kong Enterprise の紹介
Kong Enterprise の紹介
 
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
 
[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda
[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda
[C16] インメモリ分散KVSの弱点。一貫性が崩れる原因と、それを克服する技術とは? by Taichi Umeda
 

Similaire à BigQuery勉強会 Standard SQL Dialect

20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料kasaharatt
 
Maatkit で MySQL チューニング
Maatkit で MySQL チューニングMaatkit で MySQL チューニング
Maatkit で MySQL チューニングKensuke Nagae
 
2010 in-depth-v11
2010 in-depth-v112010 in-depth-v11
2010 in-depth-v11kmiyako
 
固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-
固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-
固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-歩 柴田
 
PostgreSQL13 新機能紹介
PostgreSQL13 新機能紹介PostgreSQL13 新機能紹介
PostgreSQL13 新機能紹介Satoshi Hirata
 
[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)
[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)
[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)Insight Technology, Inc.
 
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
巨大な表を高速に扱うData.table について
巨大な表を高速に扱うData.table について巨大な表を高速に扱うData.table について
巨大な表を高速に扱うData.table についてHaruka Ozaki
 
db tech showcase 2019 D10 Oracle Database New Features
db tech showcase 2019 D10 Oracle Database New Featuresdb tech showcase 2019 D10 Oracle Database New Features
db tech showcase 2019 D10 Oracle Database New FeaturesNoriyoshi Shinoda
 
Oracle In-database-archiving ~Oracleでの論理削除~
Oracle In-database-archiving ~Oracleでの論理削除~Oracle In-database-archiving ~Oracleでの論理削除~
Oracle In-database-archiving ~Oracleでの論理削除~Daiki Mogmet Ito
 
Develop Web Application with Node.js + Express
Develop Web Application with Node.js + ExpressDevelop Web Application with Node.js + Express
Develop Web Application with Node.js + ExpressAkinari Tsugo
 
JOSUG 34th Meetup
JOSUG 34th Meetup JOSUG 34th Meetup
JOSUG 34th Meetup irix_jp
 
[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...
[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...
[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...Insight Technology, Inc.
 
K010 appstat201201
K010 appstat201201K010 appstat201201
K010 appstat201201t2tarumi
 
MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析
MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析
MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析Takahiro Inoue
 
進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜
進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜
進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜Michitoshi Yoshida
 
The Art of Network Protocols - RIP編 -
The Art of Network Protocols - RIP編 -The Art of Network Protocols - RIP編 -
The Art of Network Protocols - RIP編 -kirin_gumi
 
Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)Hiraku Toyooka
 
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみようPreview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみようDaisuke Masubuchi
 

Similaire à BigQuery勉強会 Standard SQL Dialect (20)

20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
 
Maatkit で MySQL チューニング
Maatkit で MySQL チューニングMaatkit で MySQL チューニング
Maatkit で MySQL チューニング
 
2010 in-depth-v11
2010 in-depth-v112010 in-depth-v11
2010 in-depth-v11
 
固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-
固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-
固定化か?最新化か?オプティマイザ統計の運用をもう一度考える。 -JPOUG Tech Talk Night #6-
 
PostgreSQL13 新機能紹介
PostgreSQL13 新機能紹介PostgreSQL13 新機能紹介
PostgreSQL13 新機能紹介
 
[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)
[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)
[INSIGHT OUT 2011] A24 sql server wait events(mario broodbakker)
 
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
巨大な表を高速に扱うData.table について
巨大な表を高速に扱うData.table について巨大な表を高速に扱うData.table について
巨大な表を高速に扱うData.table について
 
db tech showcase 2019 D10 Oracle Database New Features
db tech showcase 2019 D10 Oracle Database New Featuresdb tech showcase 2019 D10 Oracle Database New Features
db tech showcase 2019 D10 Oracle Database New Features
 
Oracle In-database-archiving ~Oracleでの論理削除~
Oracle In-database-archiving ~Oracleでの論理削除~Oracle In-database-archiving ~Oracleでの論理削除~
Oracle In-database-archiving ~Oracleでの論理削除~
 
Develop Web Application with Node.js + Express
Develop Web Application with Node.js + ExpressDevelop Web Application with Node.js + Express
Develop Web Application with Node.js + Express
 
JOSUG 34th Meetup
JOSUG 34th Meetup JOSUG 34th Meetup
JOSUG 34th Meetup
 
[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...
[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...
[db tech showcase Tokyo 2018] #dbts2018 #D34 『サポートのトップエンジニアが語る - ワンランク上のStats...
 
DevLOVE発表資料
DevLOVE発表資料DevLOVE発表資料
DevLOVE発表資料
 
K010 appstat201201
K010 appstat201201K010 appstat201201
K010 appstat201201
 
MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析
MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析
MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析
 
進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜
進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜
進化したのはサーバだけじゃない!〜DBA の毎日をもっと豊かにするユーティリティのすすめ〜
 
The Art of Network Protocols - RIP編 -
The Art of Network Protocols - RIP編 -The Art of Network Protocols - RIP編 -
The Art of Network Protocols - RIP編 -
 
Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)
 
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみようPreview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
Preview: 世界中のゲーム分析をしてきたPlayFabが大進化!一緒に裏側の最新データ探索の仕組みを覗いてみよう
 

Plus de Ken Morishita

iOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeiOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeKen Morishita
 
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)Ken Morishita
 
知らないと損するアプリ開発におけるStateMachineの活用法(15分版)
知らないと損するアプリ開発におけるStateMachineの活用法(15分版)知らないと損するアプリ開発におけるStateMachineの活用法(15分版)
知らないと損するアプリ開発におけるStateMachineの活用法(15分版)Ken Morishita
 
SwiftでのiOSアプリ開発
SwiftでのiOSアプリ開発SwiftでのiOSアプリ開発
SwiftでのiOSアプリ開発Ken Morishita
 
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞いiOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞いKen Morishita
 
IOS/Androidアプリの3つの大事な設計方針
IOS/Androidアプリの3つの大事な設計方針IOS/Androidアプリの3つの大事な設計方針
IOS/Androidアプリの3つの大事な設計方針Ken Morishita
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テストKen Morishita
 
Logをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組みLogをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組みKen Morishita
 
Pythonとdeep learningで手書き文字認識
Pythonとdeep learningで手書き文字認識Pythonとdeep learningで手書き文字認識
Pythonとdeep learningで手書き文字認識Ken Morishita
 

Plus de Ken Morishita (9)

iOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeiOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPractice
 
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
 
知らないと損するアプリ開発におけるStateMachineの活用法(15分版)
知らないと損するアプリ開発におけるStateMachineの活用法(15分版)知らないと損するアプリ開発におけるStateMachineの活用法(15分版)
知らないと損するアプリ開発におけるStateMachineの活用法(15分版)
 
SwiftでのiOSアプリ開発
SwiftでのiOSアプリ開発SwiftでのiOSアプリ開発
SwiftでのiOSアプリ開発
 
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞いiOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
 
IOS/Androidアプリの3つの大事な設計方針
IOS/Androidアプリの3つの大事な設計方針IOS/Androidアプリの3つの大事な設計方針
IOS/Androidアプリの3つの大事な設計方針
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テスト
 
Logをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組みLogをs3とredshiftに格納する仕組み
Logをs3とredshiftに格納する仕組み
 
Pythonとdeep learningで手書き文字認識
Pythonとdeep learningで手書き文字認識Pythonとdeep learningで手書き文字認識
Pythonとdeep learningで手書き文字認識
 

Dernier

20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦Sadao Tokuyama
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 

Dernier (12)

20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 

BigQuery勉強会 Standard SQL Dialect

  • 2. 今回の内容 • Standard SQLの基本 • Standard SQLの便利機能を紹介 • (user, action, time) というイベントデータの処理例 • 間隔ベースのセッションIDを付ける • ユーザやセッションの属性とイベントデータを⼀つのテーブルにする • あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計 2
  • 4. Standard SQL Dialect • 2016年6⽉にBeta公開された書き⽅ • ⼤規模かつ複雑な処理の記述が可能 • (以前のをよく知らないので差分はわからないんですが) • BQは処理が複雑でも料⾦同じなのでかなり使いみちがある • なぜ「Standard」なのかと⾔われてもわかりません... https://cloud.google.com/blog/big-data/2016/06/bigquery-111-now-with-standard-sql-iam-and-partitioned-tables 4
  • 6. Time Partitioning • _PARTITIONTIME というのがあるらしいが、よく知らない… • https://cloud.google.com/bigquery/docs/partitioned-tables • 今の旧来のテーブルならば という形で取れます SELECT ... FROM `my_dataset.table_name_*` WHERE _TABLE_SUFFIX BETWEEN '20160720' AND FORMAT_DATE('%Y%m%d', CURRENT_DATE()) ① ② 6
  • 7. 細かいこと • JSON_EXTRACT 関数が消えた • DISTINCT がまともに動く感じになった • /* ... */ でコメントになる • 最後の結果セットをOrder Byできるサイズの上限は結構低い • 数千万レコードでもNGだったりする • ※ 完全ではないが対処法はある • 昔はTipsとしてよく⾔われていた EACH とかもう不要 7
  • 9. WITH構⽂ SELECT ... FROM ( SELECT ... FROM ( SELECT ... FROM original_data ) as A ) as B WITH A as ( SELECT ... FROM original_data ) , B as ( SELECT ... FROM A ) SELECT ... FROM B ■ 従来記法 ■ WITH記法 ⼊れ⼦地獄から解放され、上から下に処理を書けるようになった 9
  • 10. Analytic Function • 以前の Window Function (今回呼び名変わった?) • ※新しい機能ではないが紹介 • 普通のSQL(例えばMySQLの)ではできない、レコード間の演算 ができる 10
  • 11. 11 user action time 1 A 1 1 B 1 1 X 5 1 B 8 1 Z 9 2 A 2 2 B 5 2 D 10 例えば、ユーザ毎にアクセス順序でのSequence IDを付けたい user action time seq 1 A 1 1 1 B 1 2 1 X 5 3 1 B 8 4 1 Z 9 5 2 A 2 1 2 B 5 2 2 D 10 3 SELECT *, RANK() OVER (PARTITION BY user ORDER BY time) as seq FROM data ORDER BY user, seq RANK(): 1から順に連番をふる
  • 12. 12 user action time 1 A 1 1 B 1 1 X 5 1 B 8 1 Z 9 2 A 2 2 B 5 2 D 10 例えば、ユーザ毎に前回アクセスからの経過時刻をとりたい WITH add_last_time as ( SELECT *, LAG(time) OVER (PARTITION BY user ORDER BY time) as last_time FROM data ) , add_span as ( SELECT *, time - last_time as span FROM add_last_time ) select * from add_span ORDER BY user, time user action time last_time span 1 A 1 null null 1 B 1 1 0 1 X 5 1 4 1 B 8 5 3 1 Z 9 8 1 2 A 2 null null 2 B 5 2 3 2 D 10 5 5 LAG(X): ⼀つ前のXの値を取得する
  • 13. 13 user action time 1 A 1 1 B 1 1 X 5 1 B 8 1 Z 9 2 A 2 2 B 5 2 D 10 例えば、ユーザ毎に最初の2つのデータを残したい WITH add_seq as ( SELECT *, RANK() OVER (PARTITION BY user ORDER BY time) as seq FROM data ) , omit_records as ( SELECT * FROM add_seq WHERE seq <= 2 ) SELECT * FROM omit_records ORDER BY user, seq user action time seq 1 A 1 1 1 B 1 2 2 A 2 1 2 B 5 2
  • 14. Nest (⼊れ⼦) • これがかなり便利 • 普通のSQLには無い感覚なので慣れは必要だが慣れるとデータ のこねくり回しが捗ります • 保存・Scanデータ量の削減になる • user_idのような⽂字列などの場合特に 14
  • 15. 15 例えば、Actionを⾏ったユーザをAction毎にまとめる(ユーザの重複OKの場合) user action time 1 A 1 1 B 3 1 X 5 1 B 20 1 Z 22 2 A 2 2 B 30 2 X 60 3 X 4 4 B 2 4 A 4 Row action users 1 A 1 2 4 2 B 1 1 2 4 3 X 1 2 3 4 Z 1 重複しているよ? WITH action_users as ( SELECT action, ARRAY_AGG(user) as users FROM data GROUP by action ) SELECT * FROM action_users ORDER BY action ARRAY_AGG(): GROUP BYと共に使い、 値をARRAY型の1レコードにまとめる
  • 16. 16 例えば、Actionを⾏ったユーザをAction毎にまとめる(ユニークユーザの場合) user action time 1 A 1 1 B 3 1 X 5 1 B 20 1 Z 22 2 A 2 2 B 30 2 X 60 3 X 4 4 B 2 4 A 4 WITH action_users as ( SELECT action, ARRAY_AGG(user) as users FROM data GROUP by action ) , unique_action_users as ( SELECT action, ARRAY( SELECT DISTINCT user FROM UNNEST(users) as user ) as users FROM action_users ) SELECT * FROM unique_action_users ORDER BY action Row action users 1 A 1 2 4 2 B 1 2 4 3 X 1 2 3 4 Z 1 ARRAY(): Sub Queryが単⼀列の複数(0~N)レコード を返す場合に使う. UNNEST(): ARRAY型を展開する。 JOIN的になる場合と グループ単位で処理したい場合で 少し意味合いが違う感じ. Row action users 1 A 1 2 4 2 B 1 1 2 4 3 X 1 2 3 4 Z 1
  • 17. ■Group By する必要がある場合: ARRAY_AGG(STRUCT(...)) ... GROUP BY SELECT ..., ARRAY_AGG(STRUCT(col1, col2, ...)) FROM ... GROUP BY X 複数列をArray型に⼊れる⽅法 ■Group By する必要がない場合 or 何か計算処理する場合: ARRAY(SELECT STRUCT(...)) SELECT ..., ARRAY( SELECT STRUCT(col1 * 2, SUM(col2) OVER ... , ...) FROM ... ) FROM ... STRUCT(): レコード型を作る。 レコード型という単⼀列になる。
  • 19. 19 間隔ベースのセッションIDを付ける user action time 1 A 1 1 B 3 1 X 5 1 B 20 1 Z 22 2 A 2 2 B 30 2 X 35 やりたいこと: ユーザ毎にアクセス間隔が10以上なら別のSessionIDを付けるようにしたい 1 2 1 2 user action time last_time new_session session_seq 1 A 1 null 0 1 1 B 3 1 0 1 1 X 5 3 0 1 1 B 20 5 1 2 1 Z 22 20 0 2 2 A 2 null 0 1 2 B 30 2 1 2 2 X 35 30 0 2 WITH add_last_time as ( SELECT *, LAG(time) OVER (PARTITION BY user ORDER BY time) as last_time FROM data ) , add_span as ( SELECT *, IF(time - last_time >= 10, 1, 0) as new_session FROM add_last_time ) SELECT *, 1+SUM(new_session) OVER (PARTITION BY user ORDER BY time) as session_seq FROM add_span ORDER BY user, time
  • 20. user session_seq session_start_time session_end_time session_time_span actions.action actions.time 1 1 1 5 4 A 1 B 3 X 5 1 2 20 22 2 B 20 Z 22 2 1 2 2 0 A 2 2 2 30 35 5 B 30 20 ユーザやセッションの属性とイベントデータを⼀つのテーブルにする: Step1 user action time 1 A 1 1 B 3 1 X 5 1 B 20 1 Z 22 2 A 2 2 B 30 2 X 35 やりたいこと:ユーザやセッションの属性とイベントデータを⼀つのテーブルにする WITH ... 略 ... , add_session_seq as ( SELECT *, 1+SUM(new_session) OVER (PARTITION BY user ORDER BY time) as session_seq FROM add_span ) SELECT user, session_seq, MIN(time) as session_start_time, MAX(time) as session_end_time, MAX(time) - MIN(time) as session_time_span, ARRAY_AGG(STRUCT(action, time)) as actions FROM add_session_seq GROUP BY user, session_seq
  • 21. user session_seq ... actions.action actions.time 1 1 A 1 B 3 X 5 1 2 B 20 Z 22 2 1 A 2 2 2 B 30 21 ユーザやセッションの属性とイベントデータを⼀つのテーブルにする: Step2 やりたいこと:ユーザやセッションの属性とイベントデータを⼀つのテーブルにする WITH ... 略 ... , group_by_user as ( SELECT user, MAX(session_seq) as session_num, ARRAY_AGG(STRUCT( session_start_time, session_end_time, session_time_span, actions )) as sessions FROM group_by_session GROUP BY user ) SELECT * FROM group_by_user ORDER BY user user session_num sessions.session_start_time sessions.session_end_time sessions.session_time_span sessions.actions.action sessions.actions.time 1 2 1 5 4 A 1 B 3 X 5 20 22 2 B 20 Z 22 2 2 2 2 0 A 2 30 35 5 B 30 X 35
  • 22. 22 ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計 やりたいこと: Xの後に時刻10以内にZが発⽣する割合を求める user action time 1 A 1 1 X 5 1 B 9 1 Z 11 2 A 2 2 X 15 2 Z 40 3 Z 3 3 X 6 4 X 4 4 X 5 4 Z 7 1 0 (時刻10以内でない) 0 (ZがXの後で発⽣していない) 1 (最初のXに対してのみ計算するとする) X=4, Z=2 → 50% とカウントしたい
  • 23. 23 ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計 user action time 1 A 1 1 X 5 1 B 9 1 Z 11 2 A 2 2 X 15 2 Z 40 3 Z 3 3 X 6 4 X 4 4 X 5 4 Z 7 user first_x_time action_times.action action_times.time 1 5 X 5 Z 11 2 15 X 15 Z 40 3 6 Z 3 X 6 4 4 X 4 X 5 Z 7 WITH group_by_user as ( SELECT user, ARRAY_AGG(STRUCT(action, time)) as action_times FROM data WHERE action in ('X', 'Z') GROUP BY user ), pickup_first_x_timeas ( SELECT user, action_times, ( SELECT MIN(time) FROM UNNEST(action_times) WHERE action='Xʼ ) as first_x_time FROM group_by_user ) SELECT * FROM pickup_first_x_time ORDER BY user
  • 24. 24 ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計 user first_x_time action_times.action action_times.time 1 5 X 5 Z 11 2 15 X 15 Z 40 3 6 Z 3 X 6 4 4 X 4 X 5 Z 7 WITH ... , count_z as ( SELECT user, first_x_time, ( SELECT COUNT(*) FROM UNNEST(action_times) as a WHERE a.action = 'Zʼ AND a.time BETWEEN first_x_time AND first_x_time + 10 ) as z_count, action_times FROM pickup_first_x_time ) SELECT * FROM count_z ORDER BY user user first_x_time z_count action_times.action action_times.time 1 5 1 X 5 Z 11 2 15 0 X 15 Z 40 3 6 0 Z 3 X 6 4 4 1 X 4 X 5 Z 7
  • 25. 25 WITH ... SELECT COUNT(*) as x_cnt, COUNTIF(z_count > 0) as z_cnt FROM count_z user first_x_time z_count action_times.action action_times.time 1 5 1 X 5 Z 11 2 15 0 X 15 Z 40 3 6 0 Z 3 X 6 4 4 1 X 4 X 5 Z 7 ユーザ毎に, あるAction Xが発⽣した後、時刻T以内にAction Zが発⽣する割合の集計 x_cnt z_cnt 4 2
  • 26. まとめ • Standard SQLは結構強い • まだβ版なので仕様が変わる可能性もあるが、考え⽅などは変 わらないので慣れておくのは良いこと • 是⾮活⽤していきましょう! 26