按出现天数对结果进行分组
Group results by number of days appearing
我想获取某人在一个月内登录的天数。使用此查询:
select id,
to_char(date_on, 'MM-DD') as mon_dd
from
logs
group by
id, to_char(date_on, 'MM-DD')
我得到一个 table,看起来像这样:
id | mon_dd
0 | 01-27
3 | 02-23
1 | 01-05
0 | 01-31
2 | 02-01
3 | 02-05
1 | 02-09
我想得到一个结果,将 id 按它们在一个月中出现的天数分组,如下所示:
id | month | days_appeared
0 | jan | 2
0 | feb | 0
1 | jan | 1
1 | feb | 1
2 | jan | 0
2 | feb | 1
3 | jan | 0
3 | feb | 2
您可以生成 table 中不同月份和用户的笛卡尔积,然后将 table 与 left join
:
select
i.id,
d.date_month,
count(distinct trunc(l.date_on)) days_appeared
from (select distinct trunc(date_on, 'month') date_month from logs) d
cross join (select distinct id from logs) i
left join logs l
on l.date_on >= d.date_month
and l.date_on < add_months(d.date_month, 1)
and l.id = i.id
group by i.id, d.date_month
如果你想得到所有的月份,即使是那些有零的月份,那么:
select l.id, m.mon, count(distinct trunc(date_on)) as num_days
from (select distinct id from logs) i cross join
(select distinct trunc(date_on, 'month') as mon) m left join
logs l
on l.id = i.id and trunc(date_on, 'month') = m.mon
group by l.id, m.mon;
注意:与在 logs
table.
上使用 select distinct
相比,您可能拥有更有效的月份和 ID 来源
我喜欢使用 WITH 子句以模块化方式构建查询。
with vals as ( -- all information needed is here
select id
, to_char(mon_dd, 'mon') as month
, to_char(mon_dd,'mm') as mm
from logs
),
months as ( -- the distinct months,
select distinct month, mm -- including the month numbers
from vals -- for ordering the main query
),
ids as ( -- the distinct ids
select distinct id
from vals)
select i.id, m.month, (select count(id) from vals -- for every combination of id
where month=m.month -- and month
and id = i.id) as count -- count the number of ids
from ids i cross join months m
order by i.id, m.mm;
我想获取某人在一个月内登录的天数。使用此查询:
select id,
to_char(date_on, 'MM-DD') as mon_dd
from
logs
group by
id, to_char(date_on, 'MM-DD')
我得到一个 table,看起来像这样:
id | mon_dd
0 | 01-27
3 | 02-23
1 | 01-05
0 | 01-31
2 | 02-01
3 | 02-05
1 | 02-09
我想得到一个结果,将 id 按它们在一个月中出现的天数分组,如下所示:
id | month | days_appeared
0 | jan | 2
0 | feb | 0
1 | jan | 1
1 | feb | 1
2 | jan | 0
2 | feb | 1
3 | jan | 0
3 | feb | 2
您可以生成 table 中不同月份和用户的笛卡尔积,然后将 table 与 left join
:
select
i.id,
d.date_month,
count(distinct trunc(l.date_on)) days_appeared
from (select distinct trunc(date_on, 'month') date_month from logs) d
cross join (select distinct id from logs) i
left join logs l
on l.date_on >= d.date_month
and l.date_on < add_months(d.date_month, 1)
and l.id = i.id
group by i.id, d.date_month
如果你想得到所有的月份,即使是那些有零的月份,那么:
select l.id, m.mon, count(distinct trunc(date_on)) as num_days
from (select distinct id from logs) i cross join
(select distinct trunc(date_on, 'month') as mon) m left join
logs l
on l.id = i.id and trunc(date_on, 'month') = m.mon
group by l.id, m.mon;
注意:与在 logs
table.
select distinct
相比,您可能拥有更有效的月份和 ID 来源
我喜欢使用 WITH 子句以模块化方式构建查询。
with vals as ( -- all information needed is here
select id
, to_char(mon_dd, 'mon') as month
, to_char(mon_dd,'mm') as mm
from logs
),
months as ( -- the distinct months,
select distinct month, mm -- including the month numbers
from vals -- for ordering the main query
),
ids as ( -- the distinct ids
select distinct id
from vals)
select i.id, m.month, (select count(id) from vals -- for every combination of id
where month=m.month -- and month
and id = i.id) as count -- count the number of ids
from ids i cross join months m
order by i.id, m.mm;