2016-09-28 3 views
1

私は前の日に比べて新しいユーザーの獲得/損失を得る必要があるユーザートラフィックテーブルを持っています。以下の解決法ではなく、これを行うより良い方法があるかどうか疑問に思うだけです。新規ユーザーを昨日と比べて

スキーマ: -

Table Strcutre: Session_ID, session_day, user_id, product_id 

私が試してみましたか?

SELECT session_day, 
     session_count, 
     user_count - LAG(user_count, 1) OVER (ORDER BY session_day) AS gain_loss_users 
    FROM 
    (
     SELECT session_day, 
       COUNT(session_id) AS session_count, 
       COUNT(user_id) user_count 
      FROM user_traffic 
     GROUP BY session_day 
    ) X ; 
+0

は、私にはかなり固体に見えます... – JohnHC

+1

「新規」または「失われた」などとして、顧客を識別するもの - のみに基づきますあなたが提示した4つのテーブルの列? – mathguy

+0

ユーザーが初回ユーザーかリターンユーザーかを識別する他の方法はありません..問題の「新しい」部分は私を混乱させます... – Teja

答えて

1

"新しい"と "戻る"人の問題を解決しようとしました。ここに私の試みは次のとおりです。

select session_day, 
     COUNT(distinct user_id) AS user_cnt, 
     count(distinct user_id) - lag(count(distinct user_id)) 
            over (order by session_day) gain, 
     count(newu) AS newu, count(returnu) AS returnu 
    from (
      select session_id, 
       session_day, 
       user_id, 
       CASE WHEN 
       count(*) over (partition by user_id ORDER BY session_day,session_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
          = 1 
         THEN 1 
        END 
        AS newu, 
       CASE WHEN 
       lag(session_day,1) over (partition by user_id ORDER BY session_day,session_id) 
          <> 
          lag(session_day,1) over (order by session_day,session_id) 
         THEN 1 
       END AS returnu  
      from user_traffic u 
     ) 
    group by session_day 
    order by session_day; 

テストデータと出力:

create table user_traffic (session_id number(6), session_day date, 
          user_id number(6), product_id number(6)); 

insert into user_traffic values ( 1, date '2016-09-07', 101, 1); 
insert into user_traffic values ( 2, date '2016-09-07', 101, 4); 
insert into user_traffic values ( 3, date '2016-09-07', 102, 1); 
insert into user_traffic values ( 4, date '2016-09-08', 101, 2); 
insert into user_traffic values ( 5, date '2016-09-08', 101, 4); 
insert into user_traffic values ( 6, date '2016-09-09', 102, 1); 
insert into user_traffic values ( 7, date '2016-09-10', 102, 1); 
insert into user_traffic values ( 8, date '2016-09-10', 103, 3); 

SESSION_DAY  CNT  GAIN  NEW RETURNS 
----------- ---------- ---------- ---------- ---------- 
2016-09-07   2      2   0 -- 101 & 102 are new 
2016-09-08   1   -1   0   0 
2016-09-09   1   0   0   1 -- 102 returned 
2016-09-10   2   1   1   0 -- 103 is new 
+0

これは良く見えます。しかし、あなたの答えに追加したいと思います。未定義の徴候と現在の行の間にある。この出力を生成するためにどのデータベースを使用しているのか不明です。 – Teja

0

より良い方法はありませんが、より簡潔な方法があります。あなたは集計関数でウィンドウ関数を混在させることができます:

SELECT session_day, 
      COUNT(session_id) as session_count, 
      COUNT(DISTINCT user_id) as user_count, 
      (COUNT(DISTINCT user_id) - 
      LAG(COUNT(DISTINCT user_id)) OVER (ORDER BY session_day) 
     ) as gain_loss_users 
     FROM user_traffic 
    GROUP BY session_day; 

((1)ユーザーが同じ日に複数のセッションを持っている可能性があるため、私はあなたがCOUNT(DISTINCT)をしたいと仮定し、(2)2つのカウントが同じになるuser_id場合とsession_idは決してNULLです)。

+0

はLAG()から「PARTITION BY session_day」を削除する必要がありますby order byであり、クエリはすでにグループ化されているため、パーティション化しないでください。 SQL Serverで遅延が残っている場合は、結果はNULL – Matt

+1

@Matt。 。 。ありがとうございました。 –

+0

新規ユーザーの獲得と損失の数値を取得するにはどうすればよいですか? @SOaddict。 – Teja

関連する問題