2017-07-21 8 views
0

ウェブサイトへのすべての訪問者の合計timeOnSiteを計算します(生データに秒単位で格納されているので3600で除算します)。それをcontent_groupと、content_levelというカスタム変数で分割します。Unnest and totals.timeOnSite(BigQueryとGoogle Analyticsのデータ)

content_groupとcontent_levelの両方が配列内にネストされているため、timeOnSiteはインクルードとネストしていないクエリで使用された場合に膨らんだtotals.-stored変数です。 (content_groupは通常のヒット・ネストされた変数ですが、content_levelはヒット(2番目のレベルのネストされた変数)でネストされたcustomDimensionsにネストされます (WillとThomas Cはこの問題がなぜこの問題で出現するのかをよく説明しますが、 )totals.timeOnSiteメトリックに彼らのアドバイスを適用し

#StandardSQL 
SELECT 
date, 
content_group, 
content_level, 
SUM(sessions) AS sessions, 
SUM(sessions2) AS sessions2, 
SUM(time_on_site) AS time_on_site 
FROM ( 
    SELECT 
     date AS date, 
     hits.contentGroup.contentGroup1 AS content_group, 
     (SELECT MAX(IF(index=51, value, NULL)) FROM UNNEST(hits.customDimensions)) AS content_level, 
     SUM(totals.visits) AS sessions, 
     COUNT(DISTINCT CONCAT(cast(visitId AS STRING), fullVisitorId)) AS sessions2, 
     SUM(totals.timeOnSite)/3600 AS time_on_site 
    FROM `projectname.123456789.ga_sessions_20170101`, 
     unnest(hits) AS hits 
    GROUP BY 
     iso_date, content_group, content_level 
    ORDER BY 
     iso_date, content_group, content_level 
    ) 
GROUP BY iso_date, content_group, content_level 
ORDER BY iso_date, content_group, content_level 

(私はUNION_ALLを使用して複数のテーブルからデータを引っ張って計画していますので、私はサブクエリを使用しますが、私はそれは関係がないと認めので、私はその構文を省略質問)

質問:

*両方のヒットに対して「ローカルな不干渉」を行うことは可能ですか?とhits.customDimensionsので、それが膨らませないで私のクエリでtotals.timeOnSiteを使用することは可能でしょうか?

*セッションとセッション2で作成したように、サイトの滞在時間を回避することは可能ですか?

*この問題の第3の隠れた解決策はありますか?

答えて

0

私はこのような自分の質問に答えるのは奇妙に思えるかもしれませんが、スタックオーバーフローの外から私の連絡先が私を助けてくれました。

session_durationに問題が窓関数を使用することによって解決することができます(あなたがBigQueryのドキュメントでウィンドウ関数についての詳細を読むことができます:https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#analytic-functions

#StandardSQL 
SELECT 
iso_date, 
content_group, 
content_level, 
COUNT(DISTINCT SessionId) AS sessions, 
SUM(session_duration) AS session_duration 
FROM ( 
    SELECT 
     date AS iso_date, 
     hits.contentGroup.contentGroup1 AS content_group, 
     (SELECT MAX(IF(index=51, value, NULL)) FROM UNNEST(hits.customDimensions)) AS content_level, 
     CONCAT(CAST(fullVisitorId AS STRING), CAST(visitId AS STRING)) AS SessionId, 
     (LEAD(hits.time, 1) OVER (PARTITION BY fullVisitorId, visitId ORDER BY hits.time ASC) - hits.time)/3600000 AS session_duration 
    FROM `projectname.123456789.ga_sessions_20170101`, 
     unnest(hits) AS hits 
    WHERE _TABLE_SUFFIX BETWEEN "20170101" AND "20170131" 
     AND (SELECT 
       MAX(IF(index=51, value, NULL)) 
      FROM 
       UNNEST(hits.customDimensions) 
      WHERE 
       value IN ("web", "phone", "tablet") 
      ) IS NOT NULL 
    GROUP BY 
     iso_date, content_group, content_level 
    ORDER BY 
     iso_date, content_group, content_level 
    ) 
GROUP BY iso_date, content_group, content_level 
ORDER BY iso_date, content_group, content_level 

両方LEAD - OVER - PARTITION副選択でとウィンドウ関数が正しく機能するためには、WHERE節のsubsubselectが必要です。

セッションをより正確に計算する方法も提供されています。

0

私は完全にこれをテストすることができませんでしたが、私のデータセットに対して動作しているようだ:

SELECT 
    DATE, 
    COUNT(DISTINCT CONCAT(fv, CAST(v AS STRING))) sessions, 
    AVG(tos) avg_time_on_site, 
    content_group, 
    content_level 
FROM(
    SELECT 
    date AS date, 
    fullvisitorid fv, 
    visitid v, 
    ARRAY(SELECT DISTINCT contentGroup.contentGroup1 FROM UNNEST(hits)) AS content_group, 
    ARRAY(SELECT DISTINCT value FROM UNNEST(hits) AS hits, UNNEST(hits.customDimensions) AS custd WHERE index = 51) AS content_level, 
    totals.timeOnSite/3600 AS tos 
    FROM `dataset_id.ga_sessions_20170101` 
    WHERE totals.timeOnSite IS NOT NULL 
) 
CROSS JOIN UNNEST(content_group) content_group 
LEFT JOIN UNNEST(content_level) content_level 
GROUP BY 
    DATE, content_group, content_level 

私は何をしようとしたことは、データセット全体にUNNEST(hits)操作を避けるために最初です。したがって、最初のSELECTステートメントでは、content_groupcontent_levelがARRAYとして格納されます。

次のSELECTでは、希望のフィールドをグループ化している間に、これらのARRAYの両方を無効にして、合計セッション数とサイトの平均時間をカウントしました(時間を扱うときには平均を使用しました集計が必要な場合は、AVGSUMに変更してください)。

外部UNNEST(hits)が回避されたため、このクエリではtimeOnSiteが繰り返される問題は発生しません。 UNNEST(content_group)UNNEST(content_level)が発生すると、それらのARRAY内の各値は対応するtime_on_siteに一度だけ関連付けられ、重複は起こりません。

+0

このクエリの出力は、私が複製しようとしているGAのレポートと一致しませんでした。クエリーのセッションはGAと比べてGAとSUM(time_on_site)のほうが3倍大きくなりました(SUM時間をAVG時間よりも評価する方が簡単ですが、AVG時間がより有用です!)明日はもう一度やります。私がいるところでは遅れているし、まっすぐ考えることもないだろう。 –

+0

GAレポートに適用されたフィルタがこのクエリで適用されたフィルタと同じであることを確認できますか?上記のクエリではエラーが見つかりませんでした。 –

+0

もう一度試して、同じ不一致を得ました。フィルタもチェックし、内部トラフィックとスパムドメインのみをフィルタリングします(afora.ru、akuhni.byなど)。私がカスタムディメンションを使わずにクエリを実行したとき(すなわち、ネストされていない場合)、合計が正しいことがわかったので、フィルタが干渉するのはちょっと奇妙だと感じました(しかし、私はまだ初心者です。 ) –

関連する問題