<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BigQuery on Marketechlabo</title><link>https://www.marketechlabo.com/tags/bigquery/</link><description>Recent content in BigQuery on Marketechlabo</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><lastBuildDate>Wed, 23 Mar 2022 00:00:00 +0900</lastBuildDate><atom:link href="https://www.marketechlabo.com/tags/bigquery/index.xml" rel="self" type="application/rss+xml"/><item><title>GA4の計測検証をBigQueryを使って行う</title><link>https://www.marketechlabo.com/web-analytics/verify-ga4-tracking-using-bigquery/</link><pubDate>Wed, 06 Jan 2021 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/web-analytics/verify-ga4-tracking-using-bigquery/</guid><description>
&lt;p&gt;GA4の計測の検証はBigQueryエクスポートを使って行うのが普通になる。検証の方法にはいくつかあるのだが、ほかの方法だと欠点がある。
リアルタイムレポートではイベントが発生し、パラメータに値が入ってきているのはわかるが、どのイベントでどのパラメータの値が入っているかまではわからない。DebugViewは有効化しないと使えない。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BigQueryエクスポートを使うとすべてのサイト訪問に対して計測して数分以内には各パケット（イベント）でどのパラメータにどの値が入っているかがわかるし、詳細な検証ができる&lt;/strong&gt;。
GA4のBigQueryデータはパラメータやユーザープロパティがネストされているため、クエリでは毎回それをフラット化する手続きをする必要があり、やや面倒。
検証の目的に合わせて使うクエリがパターン化されるのでこの記事ではそれを紹介する。&lt;/p&gt;
&lt;h2 id="検証用のおすすめ設定"&gt;検証用のおすすめ設定&lt;/h2&gt;
&lt;h3 id="ログのストリーミング出力設定"&gt;ログのストリーミング出力設定&lt;/h3&gt;
&lt;p&gt;GA4のBigQueryエクスポート設定で&lt;strong&gt;ログ出力をストリーミングにする&lt;/strong&gt;。これを有効にすることでイベント発生から数分以内にログがBigQueryに取り込まれる。この指定をしないと1日1回しかデータが取り込まれず、翌日の朝にならないと検証ができない。設定方法は以下の「頻度」の「ストリーミング」のチェックを入れる。
&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="/images/ga4-bq-export/06-specify-data-stream.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="計測のバージョン番号をパラメータ設定する"&gt;計測のバージョン番号をパラメータ設定する&lt;/h3&gt;
&lt;p&gt;送信する変数（イベントパラメータ、ユーザープロパティ）をバージョン管理するといい。
&lt;strong&gt;イベントパラメータに現在の設定のバージョン番号を記録し、全イベントでそれを送る&lt;/strong&gt;。
GTMで送信するパラメータ／ユーザープロパティを変更する都度、バージョンを更新する。
計測された値がどの設定によるものなのか、簡単に照合できる。&lt;/p&gt;
&lt;p&gt;全イベントで共通して送るのでイベントタグでなく設定タグに入れておく。
&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="/images/ga4-verification/01-set-config-version.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id="計測バージョン番号の確認"&gt;計測バージョン番号の確認&lt;/h4&gt;
&lt;p&gt;各計測バージョンがいつからいつまで計測されていたのか、計測されたイベントの数（行数）を確認する&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p.value.string_value v_name,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;min&lt;/span&gt;(timestamp_micros(event_timestamp)) min_time,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;max&lt;/span&gt;(timestamp_micros(event_timestamp)) max_time,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;count&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) n_events
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_99999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt; t1, &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) p
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; p.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;config_version&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;group&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;order&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;desc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="/images/ga4-verification/02-verify-version.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="ページビューidについて"&gt;ページビューIDについて&lt;/h3&gt;
&lt;p&gt;同じページビューで発生したイベントをグルーピングするためのIDとして、GA4のBigQueryエクスポートには&lt;code&gt;batch_page_id&lt;/code&gt;が含まれている。同じページビューで発生したイベントはこの値が同じになるため、「あるページでバナーを閲覧→そのバナーをクリックした」などの行動を把握できる。&lt;/p&gt;
&lt;p&gt;以前はカスタムのページビューIDをGTMで設定する必要があったが、&lt;code&gt;batch_page_id&lt;/code&gt;がデフォルトで計測されるようになったため、通常はこちらを使えばよい。&lt;/p&gt;
&lt;h3 id="ページの読み込み開始タイムスタンプをパラメータ設定する"&gt;ページの読み込み開始タイムスタンプをパラメータ設定する&lt;/h3&gt;
&lt;p&gt;ページの読み込み開始からイベント発生までどのくらい時間が経過したのか、検証の観点からもユーザ行動把握の観点からも必要である。
イベント発生のタイムスタンプは常に計測される（&lt;code&gt;event_timestamp&lt;/code&gt;）が、経過時間の起点としてページの読み込み開始タイムスタンプをイベントパラメータに入れておくと、その&lt;strong&gt;差分からイベント発生までにかかった時間がわかる&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;ブラウザに格納されているページの読み込み処理のタイムスタンプにはいろいろ候補があるが、Navigation Timing API Level 2の&lt;code&gt;PerformanceNavigationTiming&lt;/code&gt;を使うのがよい。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;entries&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;performance&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getEntriesByType&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;navigation&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;entries&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;round&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;entries&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;startTime&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;performance&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;timeOrigin&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そのままGTMのカスタムJavaScript変数として登録すればいい。
&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="/images/gtm/gtm-variable-navigation-start.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="計測されているパラメータ数を見る"&gt;計測されているパラメータ数を見る&lt;/h2&gt;
&lt;h3 id="イベントごとに計測されているパラメータの種類を一覧にする"&gt;イベントごとに計測されているパラメータの種類を一覧にする&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; event_name,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; p.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;key&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;count&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) cnt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_99999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) p
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;group&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;order&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="/images/ga4-verification/03-parameters-by-event.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Google BigQueryでお手軽機械学習（BQML）</title><link>https://www.marketechlabo.com/machine-learning/bqml-intro/</link><pubDate>Mon, 18 Jan 2021 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/machine-learning/bqml-intro/</guid><description>
&lt;p&gt;BigQuery MLは生成AI（Geminiなど）との連携やVertex AI統合など多様な機能を提供しているが、企業の日常業務で扱う構造化データ（売上、顧客、在庫など）の予測分析において、最もコストパフォーマンスが高く実用的な手法は依然として勾配ブースティング木（XGBoost系）である。この記事では、SQLだけで完結するMLパイプラインの構築方法を実例とともに解説する。&lt;/p&gt;
&lt;p&gt;BigQuery ML（BQML）では以下のモデルが使える：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;線形回帰&lt;/strong&gt; - 類似のリモートデータでトレーニングされたモデルを使用して、新しいデータの数値指標の値を予測する。ラベルは実数で、正の無限大、負の無限大、NaN（非数値）にはできない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロジスティック回帰&lt;/strong&gt; - 入力がlow-value、medium-value、high-valueのいずれであるかなど、2つ以上の有効な値を分類する場合に使用する。ラベルには最大50個の一意の値を指定できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K平均法クラスタリング&lt;/strong&gt; - データセグメンテーションに使用する。顧客セグメントの識別などに使える。教師なし学習なのでモデルのトレーニングを行う際にラベルは必要なく、トレーニングや評価用にデータの分割を行う必要もない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行列分解&lt;/strong&gt; - 商品のレコメンデーションシステムの作成に使用する。過去の顧客行動、トランザクション、商品評価を使用して商品のおすすめを作成し、これらのレコメンデーションを使用してカスタマイズされたカスタマーエクスペリエンスを提供できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主成分分析（PCA）&lt;/strong&gt; - 主成分を計算し、それらを使用してデータに基底変換を実行するプロセス。一般に、データのバリエーションをできるだけ多く保持しながら、各データポイントを最初のいくつかの主成分にのみ射影して低次元のデータを取得することで、次元数を削減するために使用される。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;時系列&lt;/strong&gt; - 時系列予測と異常検出に使用する。ARIMA_PLUSモデルとARIMA_PLUS_XREGモデルは、複数のチューニングオプションを提供し、異常値、季節性、休日を自動で処理する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ディープニューラルネットワーク（DNN）&lt;/strong&gt; - 分類モデルと回帰モデル用にTensorFlowベースのディープニューラルネットワークを構築する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワイド＆ディープ&lt;/strong&gt; - レコメンデーションシステム、検索、ランキングに関する問題など、スパース入力による大規模な回帰と分類問題（多くの特徴値を持つカテゴリ特徴）に役立つ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オートエンコーダ&lt;/strong&gt; - スパースデータ表現をサポートするTensorFlowベースのモデルを作成する。BigQuery MLのモデルは、教師なし異常検出や非線形次元削減などのタスクに使用できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ブーストツリー&lt;/strong&gt; - XGBoostに基づく分類モデルと回帰モデルを作成する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ランダムフォレスト&lt;/strong&gt; - トレーニング時の分類、回帰、その他のタスク用に、複数の学習方法のディシジョンツリーを構築するために使用する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AutoML&lt;/strong&gt; - 表形式データの分類モデルと回帰モデルを高速かつ大規模に構築してデプロイする教師ありMLサービス。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当初は線形回帰とロジスティック回帰だけだったが今では実用的な手法が増えた。何よりもXGBoostが使えるようになったのが大きい。&lt;/p&gt;
&lt;h2 id="xgboostのメリット"&gt;XGBoostのメリット&lt;/h2&gt;
&lt;p&gt;XGBoostは語弊を恐れずに言うと&lt;strong&gt;特に何も考えなくてもそれなりの精度が出る、素人でもそこそこのアウトプットを出せてしまう&lt;/strong&gt;手法である。これまでの線形回帰やロジスティック回帰は前提条件が扱いが難しい手法だった。&lt;/p&gt;
&lt;p&gt;XGBoostがお手軽というのは、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正規化不要&lt;/li&gt;
&lt;li&gt;カテゴリ変数と連続量を意識しなくてもいい&lt;/li&gt;
&lt;li&gt;欠損値があってもいい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり&lt;strong&gt;特徴量の前処理の面倒な部分がかなり軽減されている&lt;/strong&gt;。与えられた変数を特に加工しなくても使える。XGBoostはそういったことが不要な、お手軽で大変便利な手法である。&lt;/p&gt;
&lt;p&gt;この記事ではBigQueryでお手軽に機械学習を体感してみようということで、XGBoostを使ってBQMLを説明する。&lt;/p&gt;
&lt;h2 id="方法"&gt;方法&lt;/h2&gt;
&lt;h3 id="データセットの準備"&gt;データセットの準備&lt;/h3&gt;
&lt;p&gt;対象データは学習（train）／評価（evaluate/validate）／テストで予測するデータに分割する。目的変数と説明変数に加え、分割用の列&lt;code&gt;subset&lt;/code&gt;を作り&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;subset = 'TRAIN'&lt;/code&gt;: 学習用データ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subset = 'EVALUATE'&lt;/code&gt;: 評価用データ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subset = 'TEST'&lt;/code&gt;: 予測用データ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という値を付与しておく。今回はBigQueryの公開サンプルデータである&lt;code&gt;bigquery-public-data.ml_datasets.ulb_fraud_detection&lt;/code&gt;を使って不正取引の予測をするモデルを作る。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Class&lt;/code&gt;が目的変数となる不正取引フラグ&lt;/li&gt;
&lt;li&gt;特徴量は&lt;code&gt;V1&lt;/code&gt;～&lt;code&gt;V28&lt;/code&gt;と&lt;code&gt;Amount&lt;/code&gt;（取引額）。&lt;code&gt;V1&lt;/code&gt;～&lt;code&gt;V28&lt;/code&gt;はオリジナルの特徴量を主成分分析で集約したもの&lt;/li&gt;
&lt;li&gt;これを学習：評価：テスト＝8:1:1で分割する&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;create&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;replace&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;table&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;my&lt;span style="color:#f92672"&gt;-&lt;/span&gt;project.test_dataset.ulb_fraud_detection&lt;span style="color:#f92672"&gt;`&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; t1 &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; row_number() over() id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rand() rnd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;bigquery&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;data&lt;/span&gt;.ml_datasets.ulb_fraud_detection&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;), t2 &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt;(rnd),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; rnd &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;TRAIN&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; rnd &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;9&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;EVALUATE&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;TEST&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; subset
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; t1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; t2 &lt;span style="color:#66d9ef"&gt;order&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="bqmlの機械学習手順"&gt;BQMLの機械学習手順&lt;/h3&gt;
&lt;p&gt;まずBQMLの操作手順だが、機械学習の手順に沿い&lt;/p&gt;</description></item><item><title>Googleアナリティクス4のBigQueryエクスポート仕様</title><link>https://www.marketechlabo.com/web-analytics/ga4-bigquery-export-spec/</link><pubDate>Thu, 11 Mar 2021 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/web-analytics/ga4-bigquery-export-spec/</guid><description>
&lt;p&gt;GA4のBigQueryエクスポートの仕様とデータの扱い方を説明する。GA4のログはネストされたレコードなど特殊な形式になっており、そのままでは扱いにくいのでいくつかテクニックがある。&lt;/p&gt;
&lt;h2 id="bigqueryへのエクスポート設定"&gt;BigQueryへのエクスポート設定&lt;/h2&gt;
&lt;p&gt;GA4の管理画面で設定するが、手順はこちらの記事を参照。
&lt;a href="https://www.marketechlabo.com/ga-app-web-property-to-bigquery/"&gt;https://www.marketechlabo.com/ga-app-web-property-to-bigquery/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="テーブルの場所"&gt;テーブルの場所&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;プロジェクト：GA4のBigQueryエクスポート設定で指定したプロジェクト&lt;/li&gt;
&lt;li&gt;データセット「&lt;code&gt;analytics_999999999&lt;/code&gt;」（「&lt;code&gt;999999999&lt;/code&gt;」の部分はプロパティID）&lt;/li&gt;
&lt;li&gt;テーブル名
&lt;ul&gt;
&lt;li&gt;前日までのデータ（日付別に）「&lt;code&gt;events_20210101&lt;/code&gt;」
&lt;ul&gt;
&lt;li&gt;「&lt;code&gt;20210101&lt;/code&gt;」の部分は日付&lt;/li&gt;
&lt;li&gt;GA4のBigQueryエクスポート設定画面の「エクスポートタイプ」で「毎日」のチェックを入れている場合に出力される&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;今日のデータ、前日未集計分のデータ「&lt;code&gt;events_intraday_20210102&lt;/code&gt;」
&lt;ul&gt;
&lt;li&gt;「&lt;code&gt;20210102&lt;/code&gt;」の部分は日付&lt;/li&gt;
&lt;li&gt;エクスポートタイプ設定で「ストリーミング」のチェックを入れている場合に出力される&lt;/li&gt;
&lt;li&gt;「ストリーミング」と「毎日」を両方オンにしている場合は毎日のテーブルが生成されるとこのテーブルが削除される&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;出力時刻は午前7-9時ごろ。レポートのタイムゾーンに依存するため、米国のままにしていると夜11時ごろに出力される。GA4ではなくFirebase Analyticsの場合はUTC。タイムゾーン設定がない。&lt;/p&gt;
&lt;h2 id="日付でシャーディングされたテーブル"&gt;日付でシャーディングされたテーブル&lt;/h2&gt;
&lt;p&gt;GA4のBigQueryエクスポートでは日単位でテーブルが分かれている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前日まで：events_20210101, events_20210102, &amp;hellip;, events_20210127&lt;/li&gt;
&lt;li&gt;当日：events_intraday_20210128&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このように一つの内容（エンティティ）を表すテーブルを実体としては異なる複数のテーブルに分けて分散格納することをシャーディング（sharding）という。BigQueryでは共通の接頭辞で、末尾が&lt;code&gt;_YYYYMMDD&lt;/code&gt;形式の日付で異なる名前のシャーディングテーブルはウェブ画面上では一つのテーブルであるかのようにまとめて表示される。&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="シャーディングテーブル"
class="image_figure image_internal image_unprocessed"
src="/images/ga4-bq-export/sharding-tables.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;シャーディングされたテーブル群ではクエリをかける際、日単位で対象のテーブルを絞り込めばメモリの節約ができる。
またクエリでも以下のようにfrom句でテーブル名を指定する際にワイルドカード&lt;code&gt;*&lt;/code&gt;を付けると、そのワイルドカード条件にマッチするテーブル名、つまり前方一致でマッチするテーブル名のすべてを対象にできる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そしてwhere句で&lt;code&gt;_table_suffix&lt;/code&gt;を使ってワイルドカードの部分の文字列を指定することができる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;where&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _table_suffix &lt;span style="color:#66d9ef"&gt;between&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;20210101&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;20210110&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上はテーブル名末尾の日付文字列部分が&lt;code&gt;20210101&lt;/code&gt;から&lt;code&gt;20210110&lt;/code&gt;の間（2021年1月1日から2021年1月10日までのログ）を対象にしたクエリだが、結果は以下と同じ。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; ... &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_20210101&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;union&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; ... &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_20210102&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;union&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; :
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; ... &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_20210110&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;_table_suffix&lt;/code&gt;はアスタリスクの部分にマッチする文字列を表す。つまり下の2つのfromは同じものを意味する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; _TABLE_SUFFIX &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;20210101&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_20210101&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;_table_suffix&lt;/code&gt;を指定してクエリ対象のテーブルを絞り込むことによって、処理するデータ量つまりクエリコストの節約ができる。単純に&lt;code&gt;from&lt;/code&gt;でワイルドカードを指定したまま&lt;code&gt;_table_suffix&lt;/code&gt;を使った絞り込みを行わないと全期間のテーブルがクエリの対象になり、そのデータサイズに対して課金される。クエリを実行する際は必ず&lt;code&gt;_table_suffix&lt;/code&gt;で期間を絞り込もう。&lt;/p&gt;
&lt;p&gt;一方でパーティショニングも同様にデータを分けて格納しているが、テーブルの実体としては一つである。シャーディングもパーティショニングもクエリを実行する際、日付単位で対象のテーブルを絞り込めばメモリの節約ができる。&lt;/p&gt;
&lt;p&gt;なおシャーディングテーブルは基本的に同じ列構成になるのだが、GA4の場合、同じシャーディングテーブル群であってもある日を境に列が追加されることがある。その場合&lt;code&gt;select *&lt;/code&gt;をすると列が一致しないというエラーが発生するので、列名もワイルドカードではなく個別に指定しなければならない。&lt;/p&gt;
&lt;h2 id="主な項目"&gt;主な項目&lt;/h2&gt;
&lt;p&gt;GA4のログは1行1イベントを表す履歴データである。1行の中にネストされたデータ構造を持つ列もある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ユーザー
&lt;ul&gt;
&lt;li&gt;ユーザー識別子&lt;/li&gt;
&lt;li&gt;ユーザープロパティ: &lt;code&gt;user_properties.***&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;イベント
&lt;ul&gt;
&lt;li&gt;イベント名: &lt;code&gt;event_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;タイムスタンプ: &lt;code&gt;event_timestamp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;バッチ処理関連
&lt;ul&gt;
&lt;li&gt;ページビューの識別子: &lt;code&gt;batch_page_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;同一ページ内での何番目の計測パケット送信なのか: &lt;code&gt;batch_ordering_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;同じ計測パケットの中でのイベントの順序: &lt;code&gt;batch_event_index&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;イベントパラメータ: &lt;code&gt;event_params.***&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;トラフィック
&lt;ul&gt;
&lt;li&gt;ユーザーの最初の流入元: &lt;code&gt;traffic_source.***&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;各イベント行における流入元: &lt;code&gt;collected_traffic_source.***&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;セッションの流入元: &lt;code&gt;session_traffic_source_last_click.***&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;デバイス関連: &lt;code&gt;device.***&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;地域: &lt;code&gt;geo.***&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;eコマース関連変数
&lt;ul&gt;
&lt;li&gt;取引に関する情報: &lt;code&gt;ecommerce.***&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;商品に関する情報: &lt;code&gt;items.***&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;同意関連: &lt;code&gt;privacy_info.***&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ストリームID: &lt;code&gt;stream_id&lt;/code&gt;（ウェブ、アプリなど1つのGA4プロパティで複数のストリームがある場合に識別する）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ユーザー"&gt;ユーザー&lt;/h3&gt;
&lt;p&gt;ユーザの識別子として2種類の列がある。&lt;/p&gt;</description></item><item><title>GA4無料版と有料版のBigQueryエクスポートの違い</title><link>https://www.marketechlabo.com/web-analytics/ga4-bigquery-export-differences/</link><pubDate>Wed, 23 Mar 2022 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/web-analytics/ga4-bigquery-export-differences/</guid><description>
&lt;h2 id="2種類のbigqueryエクスポート"&gt;2種類のBigQueryエクスポート&lt;/h2&gt;
&lt;p&gt;GA4のBigQueryエクスポートデータには以下の2種類がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;イベントデータ&lt;/li&gt;
&lt;li&gt;ユーザーデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ユーザーデータは1行1人で、&lt;code&gt;user_pseudo_id&lt;/code&gt;単位で集約したデータと、&lt;code&gt;user_id&lt;/code&gt;単位で集約したデータのそれぞれのテーブルが生成される。
所属するオーディエンスの情報やユーザ（&lt;code&gt;user_pseudo_id&lt;/code&gt; / &lt;code&gt;user_id&lt;/code&gt;）単位の通算指標が含まれる。
分析によく使うのがイベントデータで、1行1イベントでイベントパラメータなどがネストされて含まれている。&lt;/p&gt;
&lt;h2 id="エクスポートの頻度"&gt;エクスポートの頻度&lt;/h2&gt;
&lt;p&gt;イベントデータの出力頻度は以下の3種類がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ストリーミング＝リアルタイム。重複や使えない列あり（トラフィック関連の列）&lt;/li&gt;
&lt;li&gt;毎日→翌日に、前日分をまとめて、重複除外処理やトラフィック情報のアトリビューション処理済みの形で出力される&lt;/li&gt;
&lt;li&gt;毎日（高頻度）＝「毎日」のデータを当日高頻度で出力する。「ストリーミング」と「毎日」の中間だが、トラフィック関連の列は出力される&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらは設定画面の「頻度」に対応している。
&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="/images/ga4-bq-export/06-specify-data-stream.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
この中で「毎日（高頻度）」は有料版限定のオプションになる（無料版の管理画面では選択肢が表示されない）。&lt;/p&gt;
&lt;h3 id="ストリーミングデータの問題点"&gt;ストリーミングデータの問題点&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;ストリーミングデータでは重複や欠損の行が一部含まれる可能性があるのと、流入元アトリビューション処理ができておらず、&lt;code&gt;traffic_source.***&lt;/code&gt;列と&lt;code&gt;session_traffic_source_last_click.***&lt;/code&gt;が欠損して出力される&lt;/strong&gt;。
&lt;a href="https://support.google.com/analytics/answer/9358801"&gt;https://support.google.com/analytics/answer/9358801&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;このテーブルには、その日に発生したセッション アクティビティのレコードが保持されます。ストリーミング エクスポートはベスト エフォート型の処理であり、イベントの遅れやアップロードの失敗などにより、データに漏れが生じる場合もあります。データは 1 日を通して継続的にエクスポートされます。セッションが複数のエクスポート周期にまたがっていると、テーブルにはそのセッションのレコードが複数保存されることがあります。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BigQuery のストリーミング エクスポートには、新規ユーザーについては次のユーザー アトリビューション データは含まれません。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;traffic_source.name（レポート ディメンション: ユーザーのキャンペーン）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;traffic_source.source（レポート ディメンション: ユーザーの参照元）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;traffic_source.medium（レポート ディメンション: ユーザーのメディア）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;1日1回の再計算の中ではこれらを処理し、より正確なデータを生成しなおす。より正確なデータや、Googleのアトリビューションと同じロジックの流入元データ&lt;code&gt;traffic_source.***&lt;/code&gt;（「ユーザーの参照元」など）と&lt;code&gt;session_traffic_source_last_click.***&lt;/code&gt;（「セッションの参照元」など）の情報が欲しければ毎日のデータを使う必要がある。&lt;/p&gt;
&lt;h2 id="bigqueryエクスポート設定のパターンと出力されるテーブル"&gt;BigQueryエクスポート設定のパターンと出力されるテーブル&lt;/h2&gt;
&lt;p&gt;BiqQueryエクスポート設定では2個のチェックボックスがあった。2個のいずれかを選択するのではなく、それぞれチェックを入れる形式である。つまり以下の3パターンの出力設定がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ニアリアルタイムのデータのみ&lt;/li&gt;
&lt;li&gt;1日1回再計算データのみ&lt;/li&gt;
&lt;li&gt;ニアリアルタイム＋1日1回再計算&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれについて生成されるテーブル名を見ていく。
まず**データセット名はいずれも&lt;code&gt;analytics_計測ID&lt;/code&gt;**となる&lt;/p&gt;
&lt;h3 id="ニアリアルタイムデータのみ"&gt;ニアリアルタイムデータのみ&lt;/h3&gt;
&lt;p&gt;生成されるテーブル名&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;events_intraday_YYYYMMDD&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;（&lt;code&gt;YYYYMMDD&lt;/code&gt;の部分は毎日の日付が入る）
（例）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2022年3月1日の日中は
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;events_intraday_20220301&lt;/code&gt;: 2022年3月1日のリアルタイムデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2022年3月2日の日中は
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;events_intraday_20220301&lt;/code&gt;: 2022年3月1日の全データ（不完全かも）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;events_intraday_20220302&lt;/code&gt;: 2022年3月2日のリアルタイムデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2022年3月3日の日中は
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;events_intraday_20220301&lt;/code&gt;: 2022年3月1日の全データ（不完全かも）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;events_intraday_20220302&lt;/code&gt;: 2022年3月2日の全データ（不完全かも）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;events_intraday_20220303&lt;/code&gt;: 2022年3月3日のリアルタイムデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というテーブルが存在することになる。&lt;/p&gt;</description></item><item><title>GA4/Firebaseのログをフラット化する汎用クエリ</title><link>https://www.marketechlabo.com/web-analytics/ga4-firebase-log-preprocessing/</link><pubDate>Thu, 27 Jan 2022 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/web-analytics/ga4-firebase-log-preprocessing/</guid><description>
&lt;p&gt;GA4（Firebase）のログを扱う際、ネストされているイベントパラメータやユーザープロパティをフラット化しないと使いにくい。ところが格納されているパラメータやプロパティは決まっているわけではないため、通常はそれをハードコーディングで指定することが多い。つまり使用しているパラメータやプロパティに応じて&lt;strong&gt;その都度クエリを手動作成することになる&lt;/strong&gt;。
しかしそれでは面倒なので、どんなイベントパラメータやユーザープロパティを使っていても、それがどんな型であっても、オールマイティにフラット化するクエリを作る。存在するパラメータやプロパティに基づいて動的にクエリを作って実行する。&lt;strong&gt;このクエリひとつあればどんなケースにも対応できる&lt;/strong&gt;、汎用的なものである。&lt;/p&gt;
&lt;h2 id="イベントパラメータユーザープロパティ名を使った動的クエリ"&gt;イベントパラメータ（ユーザープロパティ）名を使った動的クエリ&lt;/h2&gt;
&lt;p&gt;フラット化の詳細はこちらを参照。
&lt;a href="https://www.marketechlabo.com/ga4-bigquery-export-spec/"&gt;https://www.marketechlabo.com/ga4-bigquery-export-spec/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;たとえばネストされたイベントパラメータ&lt;code&gt;ga_session_id&lt;/code&gt;（整数型）と&lt;code&gt;page_location&lt;/code&gt;（文字列型）をフラット化するクエリは&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_pseudo_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; event_name,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; p.value.int_value &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) p &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; p.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ga_session_id&amp;#34;&lt;/span&gt;) ga_session_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; p.value.string_value &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) p &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; p.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;page_location&amp;#34;&lt;/span&gt;) page_location
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;bigquery&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;data&lt;/span&gt;.ga4_obfuscated_sample_ecommerce.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;なおこの記事ではGoogleが公開しているサンプルデータセット&lt;code&gt;bigquery-public-data.ga4_obfuscated_sample_ecommerce&lt;/code&gt;を使っている。実際のプロジェクトでは自身のプロジェクトとデータセットに差し替えること。&lt;/p&gt;
&lt;p&gt;この中で動的になるのは以下の部分&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; p.value.&lt;span style="color:#960050;background-color:#1e0010"&gt;【動的：型】&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) p &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; p.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;【動的：パラメータ名】&amp;#34;&lt;/span&gt;) &lt;span style="color:#960050;background-color:#1e0010"&gt;【動的：パラメータ名】&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここに入る値は&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ga_session_id&lt;/code&gt;の場合、&lt;code&gt;p.value.int_value&lt;/code&gt;と&lt;code&gt;&amp;quot;ga_session_id&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;page_location&lt;/code&gt;の場合、&lt;code&gt;p.value.string_value&lt;/code&gt;と&lt;code&gt;&amp;quot;page_location&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;である。なおBigQueryではマルチバイト文字を列名にする際はバッククォートで囲む必要があり、列名の部分に日本語がある場合バッククォートを入れないとエラーになる。動的に実行する場合はパラメータ名をそのまま列名にすることになるため、パラメータ名に日本語を入れると不都合である。このような&lt;strong&gt;動的処理をすることを踏まえるとパラメータ名には日本語を使わないほうがいい&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;イベントパラメータではなくユーザープロパティの場合も同様にできる。つまり&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;イベントパラメータ（ユーザープロパティ）名と型の一覧を取得し、ループで文字列として代入し、SQL文を生成する&lt;/li&gt;
&lt;li&gt;そのSQL文をクエリとして実行する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ことが求められる。&lt;/p&gt;
&lt;h2 id="同じイベントパラメータに複数の型が混在する対策"&gt;同じイベントパラメータに複数の型が混在する対策&lt;/h2&gt;
&lt;p&gt;変数の型によって格納されるカラムは異なる。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;変数の型&lt;/th&gt;
&lt;th&gt;列名&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;string&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;event_params.value.string_value&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;event_params.value.int_value&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;float64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;event_params.value.double_value&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;（タイムスタンプや&lt;code&gt;date&lt;/code&gt;など、これ以外の型はイベントパラメータでは扱われない）&lt;/p&gt;
&lt;p&gt;同じパラメータに複数の型が混在するケースがある。例えば16進数として生成された値では、たまたま数字だけで構成された値は整数（&lt;code&gt;int64&lt;/code&gt;）になるし、A-Fの文字が入ると文字列（&lt;code&gt;string&lt;/code&gt;）になる。それぞれ&lt;code&gt;p.value.int_value&lt;/code&gt;と&lt;code&gt;p.value.string_value&lt;/code&gt;という別の列に格納される。つまりそれぞれの列から値を取得することになる。&lt;/p&gt;
&lt;p&gt;さらに出力を「1パラメータ＝1列」として格納するため型を合わせる（キャスト）必要がある。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_pseudo_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; event_name,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; p.value.string_value &lt;span style="color:#66d9ef"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; safe_cast(p.value.string_value &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; string)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; p.value.int_value &lt;span style="color:#66d9ef"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; safe_cast(p.value.int_value &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; string)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; p.value.double_value &lt;span style="color:#66d9ef"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; safe_cast(p.value.double_value &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; string)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) p &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; p.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;param1&amp;#34;&lt;/span&gt;) param1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;bigquery&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;data&lt;/span&gt;.ga4_obfuscated_sample_ecommerce.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ところがどの型にキャストすればいいのかが問題になるが、&lt;/p&gt;</description></item><item><title>ウェブログからSQLで指標を計算する8構文～GA4のBigQueryを題材に</title><link>https://www.marketechlabo.com/web-analytics/weblog-metrics-ga4/</link><pubDate>Thu, 05 Nov 2020 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/web-analytics/weblog-metrics-ga4/</guid><description>
&lt;p&gt;Googleアナリティクス4プロパティが登場し、&lt;a href="/ga-app-web-property-to-bigquery/"&gt;誰でもBigQueryにログを出力できるようになった&lt;/a&gt;。ログ分析を始める環境は揃ったわけだが、ログ分析のノウハウはあまり世に出ていない。SQLを使ってこれらを分析する方法を少し紹介する。どんな高度なログ分析をするにしても、これが基本となる。&lt;/p&gt;
&lt;h2 id="ウェブ分析の指標"&gt;ウェブ分析の指標&lt;/h2&gt;
&lt;p&gt;ウェブ分析の基本は&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ページビュー数&lt;/li&gt;
&lt;li&gt;セッション数&lt;/li&gt;
&lt;li&gt;人数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;のカウントである。複雑な分析も、結局カウントしているのは&lt;strong&gt;この3つの指標に集約される&lt;/strong&gt;ことが多い。Eコマースになると購入金額の合計なども入ってくることはある。&lt;/p&gt;
&lt;p&gt;そしてこれに「○○した」という条件が付いて&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;イベント○○が発生した回数
&lt;ul&gt;
&lt;li&gt;○○したページビュー数
&lt;ul&gt;
&lt;li&gt;パラメータ△△の値が□□だったイベント○○が発生した回数（ページ□□のページビュー数）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;○○したセッション数&lt;/li&gt;
&lt;li&gt;○○した人数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;をひたすらカウントする。たとえば&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;資料ダウンロードボタンをクリックした回数&lt;/li&gt;
&lt;li&gt;80％以上スクロールしたページビュー数&lt;/li&gt;
&lt;li&gt;自然検索から流入したセッション数&lt;/li&gt;
&lt;li&gt;コンバージョン完了ページを見た人数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;である。これらも&lt;strong&gt;ページビュー数／セッション数／PV数のカウントであるのは同じで、「○○した」条件に絞り込んでカウントしているだけ&lt;/strong&gt;である。&lt;/p&gt;
&lt;p&gt;そして絶対数だけでなく率の指標&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;○○したセッション率（セッション単位CVRなど）&lt;/li&gt;
&lt;li&gt;○○した人数率（ユーザ単位CVRなど）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を計算して歩留まりを見る。これに&lt;strong&gt;さまざまなディメンションをかけて比較するだけ&lt;/strong&gt;で、見ている指標はほとんどこれだけなのである。&lt;/p&gt;
&lt;h2 id="指標をbigqueryからsqlで計算する"&gt;指標をBigQueryからSQLで計算する&lt;/h2&gt;
&lt;h3 id="無条件の単純なページビュー数セッション数人数のカウント"&gt;無条件の単純なページビュー数／セッション数／人数のカウント&lt;/h3&gt;
&lt;p&gt;GA4に限らずログ分析の原則として、1行1ページビューになっていれば
ページビュー数は行数のカウント&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#960050;background-color:#1e0010"&gt;ユーザ&lt;/span&gt;ID)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;セッション数はユニークなセッションIDの数のカウント&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;セッション&lt;/span&gt;ID)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ユーザ数はユニークなユーザIDの数のカウント&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;ユーザ&lt;/span&gt;ID)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;となる。&lt;/p&gt;
&lt;p&gt;GA4の形式の場合、ページビュー数（ページビューイベントが発生した回数）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHEN&lt;/span&gt; event_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;page_view&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;THEN&lt;/span&gt; user_pseudo_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;ELSE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; n_pageviews
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;event_name = 'page_view'&lt;/code&gt;である行数をカウントする。&lt;/p&gt;
&lt;p&gt;総人数&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; user_pseudo_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) n_visitors
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ユーザを特定する列&lt;code&gt;user_pseudo_id&lt;/code&gt;（明示的にSDK内でユーザーIDを設定している場合は&lt;code&gt;user_id&lt;/code&gt;を使う。いずれも文字列型）があるので、これをユニークカウントする。&lt;/p&gt;
&lt;p&gt;総セッション数&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CONCAT(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_pseudo_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;CAST&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; ep.value.int_value &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;UNNEST&lt;/span&gt;(event_params) ep &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; ep.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ga_session_id&amp;#39;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; string
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; n_sessions
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;prj.analytics_999999999.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;GA4の仕様で、単体でユニークなセッションを特定するIDを指す列はない。&lt;strong&gt;ユーザごとのセッションを特定する&lt;/strong&gt;（あくまでユーザ内なのでグローバルにセッションを特定できるわけではない）変数がページビューイベントのパラメータ&lt;code&gt;ga_session_id&lt;/code&gt;（整数型）になる。&lt;/p&gt;</description></item></channel></rss>