2017-11-29 12 views
0

各購読がアクティブだった期間がある場合は、アクティブな購読について毎週のデータを取得する方法はありますか? 私はサブスクリプションのリストとのBigQuery内のテーブルを持っている:Google BigQueryの時間帯からの購読の週別内訳を取得

+-----------------+---------+---------------+--------------+ 
| subscription_id | user_id | subscribed_at | cancelled_at | 
+-----------------+---------+---------------+--------------+ 
|    1 |  2 | 2017-01-05 | 2017-06-03 | 
|    2 |  3 | 2017-01-07 | 2017-09-15 | 
|    3 |  4 | 2017-01-09 | NULL   | 
|    4 |  1 | 2017-01-11 | 2017-05-27 | 
|    5 |  3 | 2017-01-15 | NULL   | 
+-----------------+---------+---------------+--------------+ 

私はそれぞれのユニークなsubscription_id + active_week組み合わせのレコードを取得する必要があります。このようなもの:

+-----------------+---------+---------------+--------------+-------------+ 
| subscription_id | user_id | subscribed_at | cancelled_at | active_week | 
+-----------------+---------+---------------+--------------+-------------+ 
|    1 |  2 | 2017-01-05 | 2017-06-03 |  201701 | 
|    2 |  3 | 2017-01-07 | 2017-09-15 |  201701 | 
|    1 |  2 | 2017-01-05 | 2017-06-03 |  201702 | 
|    2 |  3 | 2017-01-07 | 2017-09-15 |  201702 | 
|    3 |  4 | 2017-01-09 | NULL   |  201702 | 
|    4 |  1 | 2017-01-11 | 2017-05-27 |  201702 | 
|    1 |  2 | 2017-01-05 | 2017-06-03 |  201703 | 
|    2 |  3 | 2017-01-07 | 2017-09-15 |  201703 | 
|    3 |  4 | 2017-01-09 | NULL   |  201703 | 
|    4 |  1 | 2017-01-11 | 2017-05-27 |  201703 | 
|    5 |  3 | 2017-01-15 | NULL   |  201703 | 
|    ... |  ...| ...   |...   |   ... | 
+-----------------+---------+---------------+--------------+-------------+ 

私はthisから行ってみましたが、運はありませんでした。

SELECT 
    SPLIT(RPAD('', 1 + DATEDIFF(sub.ended_date, sub.started_date), '.'),'') AS weeks, 
    sub.subscription_Id, 
    sub.customer_id 
FROM (
    SELECT 
    subscribed_at AS started_date, 
    CASE 
     WHEN cancelled_at IS NULL THEN TIMESTAMP(CURRENT_DATE()) 
     ELSE TIMESTAMP(cancelled_at) 
    END AS ended_date, 
    subscription_id, 
    customer_id 
    FROM 
    [subscriptions]) AS sub 

ご協力いただきありがとうございます。 - それは、余分な存在である理由私はあなたのsubscribed_atcancelled_atフィールドを前提とSTRINGデータ型である:

ベスト、 デニス・以下

+1

ようこそ!純粋なコードの書き込み要求は、スタックオーバーフローに関するトピックではありません。ここでは特定のプログラミング問題に関連する質問がありますが、私たちはあなた自身で書くことを喜んで支援します! [あなたが試したこと](https://stackoverflow.com/help/how-to-ask)とあなたが立ち往生しているところを教えてください。これはまた、あなたの質問によく答えるのにも役立ちます。 – WhatsThePoint

+0

これは、開始に役立つはずです。https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#extract –

+0

あなたが試したこととあなたの持つ問題を示すだけでそこからそれを選んでください:o) –

答えて

0

#standardSQL 
WITH temp AS (
    SELECT subscription_id, user_id, 
    PARSE_DATE('%Y-%m-%d', subscribed_at) subscribed_at, 
    PARSE_DATE('%Y-%m-%d', cancelled_at) cancelled_at 
    FROM `project.dataset.subscriptions` 
), weeks AS (
    SELECT 
    wk week_start, 
    DATE_ADD(wk, INTERVAL 6 DAY) week_end 
    FROM (
    SELECT GENERATE_DATE_ARRAY(
     DATE_TRUNC(MIN(subscribed_at), WEEK), 
     CURRENT_DATE(), INTERVAL 1 WEEK) weeks 
    FROM temp 
), UNNEST(weeks) wk 
) 
SELECT subscription_id, user_id, subscribed_at, cancelled_at, week_start, week_end 
FROM weeks 
JOIN temp 
ON subscribed_at <= week_end 
AND IFNULL(cancelled_at, CURRENT_DATE()) > week_start 

ますのでご注意くださいBigQueryの標準SQLのためでありますtempサブクエリは、フィールドをDATEフィールドとしてキャストします。元のテーブルの各フィールドがすでにDATEデータ型の場合は、tempの使用を削除し、代わりに `project.dataset.subscriptions`を使用してください。

あなたはテスト/

#standardSQL 
WITH `project.dataset.subscriptions` AS (
    SELECT 1 subscription_id, 2 user_id, '2017-01-05' subscribed_at, '2017-06-03' cancelled_at UNION ALL 
    SELECT 2, 3, '2017-01-07', '2017-09-15' UNION ALL 
    SELECT 3, 4, '2017-01-09', NULL UNION ALL 
    SELECT 4, 1, '2017-01-11', '2017-05-27' UNION ALL 
    SELECT 5, 3, '2017-01-15', NULL 
), temp AS (
    SELECT subscription_id, user_id, 
    PARSE_DATE('%Y-%m-%d', subscribed_at) subscribed_at, 
    PARSE_DATE('%Y-%m-%d', cancelled_at) cancelled_at 
    FROM `project.dataset.subscriptions` 
), weeks AS (
    SELECT 
    wk week_start, 
    DATE_ADD(wk, INTERVAL 6 DAY) week_end 
    FROM (
    SELECT GENERATE_DATE_ARRAY(
     DATE_TRUNC(MIN(subscribed_at), WEEK), 
     CURRENT_DATE(), INTERVAL 1 WEEK) weeks 
    FROM temp 
), UNNEST(weeks) wk 
) 
SELECT subscription_id, user_id, subscribed_at, cancelled_at, week_start, week_end 
FROM weeks 
JOIN temp 
ON subscribed_at <= week_end 
AND IFNULL(cancelled_at, CURRENT_DATE()) > week_start 
ORDER BY week_start, subscription_id 

次のようにあなたの質問からダミーデータを使用して上記のクエリで遊ぶことができます。また注意:上記のクエリで - あなたは月曜日から始まる週をカウントしたい場合は、週は日曜日
から始まります - あなたは少しweek_startとweek_endを調整する必要がありますweeks CTE - 以下のように

DATE_ADD(wk, INTERVAL 1 DAY) week_start, 
    DATE_ADD(wk, INTERVAL 7 DAY) week_end 
+0

ありがとうMikhail! これは機能します。 Standard SQLに関する良い本をお勧めしますか? – syned

+0

私はこれをお勧めします - https://cloud.google.com/bigquery/docs/reference/standard-sql/ –

関連する問題