2017-07-14 8 views
0

毎月のアクティブユーザー(年齢別)を調べようとしています。サブクエリで試しましたが、エラーが発生します。これを行うためのまともな方法がありますか?ありがとう!まずPOSTGRESQL:異なる日付の計算を実行する方法

with first_date_of_month as 
(
SELECT current_date - (interval '1 month' * s.a) AS dates FROM 
generate_series(0,24,1) AS s(a) 
) 


select q1.dates from first_date_of_month 
where exists (select 
case when round ((CURRENT_DATE - date_of_birth)/365) =<18 then '0-18' 
    ... 
    when round ((CURRENT_DATE - date_of_birth)/365) >= 65 then '65+' 
    Else 'N/A' end as "Age", 
    count(1) 
from users 
and signup_date between q1.dates-INTERVAL '2 months' and q1.dates 
group by 1 order by 1) ; 
+0

あなたの質問は全く意味がありません。サンプルデータと必要な結果を表示してみてください。 –

答えて

1

generate_series()は、タイムスタンプを扱うことができます:

test=# select * from generate_series('2017-01-01', now(), interval '1 month'); 
    generate_series 
------------------------ 
2017-01-01 00:00:00+00 
2017-02-01 00:00:00+00 
2017-03-01 00:00:00+00 
2017-04-01 00:00:00+00 
2017-05-01 00:00:00+00 
2017-06-01 00:00:00+00 
2017-07-01 00:00:00+00 
(7 rows) 

第二には、年齢を取得するための特別な機能があり、それは驚くほどage()と呼ばれ、間隔を返します:

test=# select age(now(), '1981-11-18'); 
        age 
----------------------------------------- 
35 years 7 mons 26 days 03:07:41.561932 

次に、あなたは間隔を置いて年を抽出できます。extract()

test=# select extract(year from age(now(), '1981-11-18')); 
date_part 
----------- 
     35 
(1 row) 

最後に、私が理解する限り、あなたは月ごとに年齢別にグループ化されたユーザー数を取得したいと思うので、2段階のグループ化が必要です。

結果(2番目のCTEステージで暗黙的なCROSS JOINを使用していますが、最終的には、メインのCTEクエリで必要だった「年齢」グループの数を減らしています。グループ「生の」年齢は既に得られている):

with dates(month) as (
    select generate_series(
    date_trunc('day', now() - interval '2 year'), 
    now(), interval '1 month' 
) 
), usrs_full_age as (
    select 
    month, 
    extract(year from age(now(), date_of_birth)) as age, 
    count(*) as count 
    from users u, dates 
    where signup_date between month - interval '2 month' and month 
    group by 1, 2 
) 
select 
    month::date, 
    case 
    when age <= 18 then '0-18' 
    -- ... 
    else 'N/A' -- NULLs will go here (records with empty date_of_birth) 
    end as age, 
    sum(count) as count 
from usrs_full_age 
group by 1, 2 
order by 1, 2 
; 
関連する問題