2016-10-03 5 views
0

postgresでLAG()およびLEAD()関数を使用してテーブル内の他の行/レコードから値を取得しようとしています。この機能は、LAG関数またはLEAD関数が同じ月の日付のみを参照している限り、意図したとおりに機能します(つまり、6月2日は6月1日を振り返りますが、5月31日を振り返るとNULL値を取得します) 。ここでLag()関数を使用して日付間で値を取得する

は、私が最初に到着したユーザーの数を取得するために、6月1日に「先読み」しようとすると、テーブルがそのテーブルから

_date count_daily_active_users count_new_users day1_users users_arriving_today_who_returned_tomrrow day_retained_users 
5/27/2013 1742 335 266 207 0.617910448 
5/28/2013 1768 241 207 146 0.605809129 
5/29/2013 1860 272 146 161 0.591911765 
5/30/2013 2596 841 161 499 0.59334126 
5/31/2013 2837 703 499 NULL NULL 
6/1/2013 12881 10372 0 5446 0.525067489 
6/2/2013 14340 6584 5446 2781 0.422387606 
6/3/2013 12222 3690 2781 1494 0.404878049 
6/4/2013 25861 17254 1494 8912 0.516517909 

どのように見えるか、あなたが5月31日にそれを見ることができます6月1日に再び返されました。私はNULL値を取得します。これは毎月の境界で起こり、「先を見よう」と思う日数に関係なく起こります。だから私が2日先を見れば、5月30日と5月31日にはNULLが返ってくるでしょう。

ここで私は私が何を私はおそらく行う必要があることのような何か付加価値整数として日付を報告し、その内側の選択で追加のフィールドを追加するためのEPOCH時間ということだと思い

SELECT 
    timestamp_session::date AS _date 
    , COUNT(DISTINCT dim_player_key) AS count_daily_active_users 
    , COUNT(DISTINCT CASE WHEN days_since_birth = 0 THEN dim_player_key ELSE NULL END) AS count_new_users 
    , COUNT(DISTINCT CASE WHEN days_since_birth != 0 THEN dim_player_key ELSE NULL END) AS count_returning_users 
    , COUNT(DISTINCT CASE WHEN days_since_birth = 1 THEN dim_player_key ELSE NULL END) AS day1_users -- note: the function is a LAG function instead of a LEAD function because of the sort order 
    , (NULLIF(LAG(COUNT(DISTINCT CASE WHEN days_since_birth = 0 THEN dim_player_key ELSE NULL END), 1) OVER (order by _date)::float, 0)) as AA 
    , (NULLIF(LAG(COUNT(DISTINCT CASE WHEN days_since_birth = 1 THEN dim_player_key ELSE NULL END), 1) OVER (order by _date)::float, 0)) as AB 
    , (NULLIF(LAG(COUNT(DISTINCT CASE WHEN days_since_birth = 0 THEN dim_player_key ELSE NULL END), 0) OVER (order by _date)::float, 0)) as BB 
    , (NULLIF(LAG(COUNT(DISTINCT CASE WHEN days_since_birth = 1 THEN dim_player_key ELSE NULL END), 0) OVER (order by _date)::float, 0)) as BA  

FROM (SELECT sessions_table.account_id AS dim_player_key, 
    sessions_table.session_id AS dim_session_key, 
    sessions_table.title_id AS dim_title_id, 
    sessions_table.appid AS dim_app_id, 
    sessions_table.loginip AS login_ip, 
    essions_table.logindate AS timestamp_session,  
    birthdate_table.birthdate AS timestamp_birthdate,  
    EXTRACT(EPOCH FROM (sessions_table.logindate - birthdate_table.birthdate)) AS count_age_in_seconds, 
    (date_part('day', sessions_table.logindate)- date_part('day', birthdate_table.birthdate)) AS days_since_birth  

    FROM 
    dataset.tablename1 AS sessions_table 
    JOIN ( 
     SELECT  
     account_id, 
     MIN(logindate) AS birthdate 
    FROM 
     dataset.tablename1  
     GROUP BY 
     account_id) 
    -- call this sub-table the birthdate_table 
    birthdate_table ON 
    sessions_table.account_id = birthdate_table.account_id 
    -- call this table the outer_sessions_table 
    ) AS outer_sessions_table 
GROUP BY 
    _date 
ORDER BY 
    _date ASC 

を書いたSQLですその日の真夜中。しかし、私がそれを試してみると(1日のエポックタイムを追加すると)、出力テーブルのすべての値が1に変わります。なぜそれが理解できません。

誰でもお手伝いできますか?

おかげで、 ブラッド

答えて

0

問題はdays_since_birth計算していました。それは私の日では、これらの日付の差を与えるために絶対的な日付を引いたかのように私は

(date_part('day', 
    sessions_table.logindate)- date_part('day', 
    birthdate_table.birthdate)) AS days_since_birth 

を使用していたが、それはちょうど月のロールにして、月の日に日付を変換して、それを差し引いていますそれ以上、-27、-29、-30(月に応じて)を返します。私はこれをABS機能でラップして修正することができます。

関連する問題