、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
;
あなたの質問は全く意味がありません。サンプルデータと必要な結果を表示してみてください。 –