2015-11-23 69 views
0

我有一個表paid_users看起來像這樣:我想確定付費用戶的月 - 年分組查詢查找付費客戶和流失客戶的數量?

http://sqlfiddle.com/#!15/d25ba

和流失的客戶按月年分組。基本上,有付款人和用戶。付款人是爲該特定用戶付款的人。如果沒有payment_stop_date,這意味着付款人仍在爲用戶付款。 payment_stop_date指示付款人是否/何時停止爲用戶付款。

我想在其中找到查​​詢的結果應該是付費用戶的數量:

Month-Year | New Paying Customers | Churned Paying Customers 
------------------------------------------------------------ 
11-2014 | 1     | 
12-2014 |      | 1 
01-2015 | 1     | 
04-2015 |      | 
06-2015 | 2     | 
07-2015 | 1     | 
10-2015 |      | 1 

在payor_id 3453來看,她開始在11-2014支付user_ID的3182,這樣她就被列入在11-2014組中。但是,她在12-2014年停止爲兩名用戶付款,因此被包括在12-2014年的小組中。如果付款人完全停止付款(即,他們本可以爲一個人付款,然後取消付款,或者在這種情況下,payor_id 3453爲2個用戶付款,然後取消),則認爲付款人是轉賬付款客戶。 Payor_3453然後在01-2015開始爲user_id 4716付款,然後她被包含在01-2015組中。

我有困難寫查詢這個,因爲它並不一定明顯payor_id因爲payor_id 3453被認爲是一種新的付費客戶兩次

回答

1

不知道我理解這個正確的:每個月你想知道有多少客戶開始爲他們的第一個用戶付費,有多少客戶停止爲他們的最後一個用戶付款?

解決方案似乎相當複雜,但也許並不是那麼容易。

with months as 
(
    select * from 
    generate_series('2014-06-01', now() at time zone 'utc', interval '1 month') as month 
    cross join paid_users 
) 
, sums as 
(
    select month, payor_id, joiners, leavers, sum(net) over (partition by payor_id order by month) 
    from 
    (
     select month, payor_id, joiners, leavers, coalesce(joiners,0) - coalesce(leavers, 0) as net 
     from 
     (
      select payor_id, month, count(*) as joiners 
      from months 
      where payment_start_date >= month 
      and payment_start_date < month + interval '1 month' 
      group by month, payor_id 
     ) as t 
     full join 
     (
      select payor_id, month, count(*) as leavers 
      from months 
      where payment_stop_date >= month 
      and payment_stop_date < month + interval '1 month' 
      group by month, payor_id 
     ) as u 
     using (month, payor_id) 
    ) as v 
) 

select * from sums 
order by payor_id, sum 

上面應該給你總付費用戶爲每一位客戶

 month  | payor_id | joiners | leavers | sum 
---------------------+----------+---------+---------+----- 
2014-06-01 00:00:00 |  1725 |  1 |   | 1 
2014-06-01 00:00:00 |  1929 |  1 |   | 1 
2015-10-01 00:00:00 |  1929 |   |  1 | 0 
2014-06-01 00:00:00 |  1986 |  1 |   | 1 
2014-11-01 00:00:00 |  3453 |  2 |   | 2 
2014-12-01 00:00:00 |  3453 |   |  2 | 0 
2015-01-01 00:00:00 |  3453 |  1 |   | 1 
2015-03-01 00:00:00 |  3453 |  1 |   | 2 
2015-04-01 00:00:00 |  3453 |  2 |  1 | 3 
2015-05-01 00:00:00 |  3453 |   |  1 | 2 
2015-06-01 00:00:00 |  3453 |   |  1 | 1 
2015-10-01 00:00:00 |  3453 |  1 |   | 2 
2015-07-01 00:00:00 |  6499 |  1 |   | 1 
2015-08-01 00:00:00 |  6499 |  3 |   | 4 
2015-10-01 00:00:00 |  6499 |   |  1 | 3 
2015-11-01 00:00:00 |  6499 |   |  1 | 2 

所以新的客戶是誰,從和0到一個非零和的客戶,流失的客戶是客戶誰達到總和爲0?

select month, new, churned from 
(
    (
     select month, count(*) as churned 
     from sums 
     where sum = 0 
     group by month 
    ) as l 
    full join 
    (
     select month, count(*) as new 
     from (
      select month, payor_id, sum, coalesce(lag(sum) over (partition by payor_id order by month), 0) as prev_sum 
      from sums 
      order by payor_id, month 
     ) as t 
     where prev_sum = 0 and sum > 0 
     group by month 
    ) as r 
    using (month) 
) 
order by month 

輸出

 month  | new | churned 
---------------------+-----+--------- 
2014-06-01 00:00:00 | 3 |   
2014-11-01 00:00:00 | 1 |   
2014-12-01 00:00:00 |  |  1 
2015-01-01 00:00:00 | 1 |   
2015-07-01 00:00:00 | 1 |   
2015-10-01 00:00:00 |  |  1 

希望這有助於。如果有人知道更簡單的方法,我很樂意聽到它。

+0

這似乎很合理,你絕對解釋了這個問題的想法比我更好 - 非常感謝你的幫助!數字看起來是正確的,邏輯很有意義:) –