使用generate_series查询并左联接时是否存在重复值?

时间:2018-12-28 16:20:52

标签: sql postgresql

我试图在特定日期对不同表中的数据进行计数,但是由于某种原因,我得到了错误的结果,它只是重复了另一张表中的计数。

如果您查看的话,则在“项目”表中只有1个条目。但是,当通过count()进行计数时,我得到了5。

你能解释并帮助我解决这个问题吗?

数据:

create table views(id bigint, created_at timestamp);
create table items(id bigint, created_at timestamp);

insert into views(id, created_at) values
('1', '2018-12-28 22:46:35'),
('2', '2018-12-28 22:46:35'),
('3', '2018-12-28 22:46:35'),
('4', '2018-12-28 22:46:35'),
('5', '2018-12-28 22:46:35');

insert into items(id, created_at) values
('1', '2018-12-28 22:46:35');

查询:

select 
dates.d as day,
count(v.*) as views_count,
count(i.*) as items_count

from (
    select d from generate_series('2018-12-01'::date, '2018-12-30', '1 day' ) as d
) as dates

left join views as v on v.created_at::date = dates.d
left join items as i on i.created_at::date = dates.d

group by day order by day desc;

DbFiddle.

3 个答案:

答案 0 :(得分:1)

count(<expression>)计算<expression>不是NULL的行数。

我认为您想计算不同值的数量。如果是这样:

select dates.d as day,
       count(distinct v.id) as views_count,
       count(distinct i.id) as items_count

您也可以使用v.*i.*作为参数,但是id应该足够。

答案 1 :(得分:0)

是因为您的views表。您有一个内部选择,可在2012/12的每一天返回。然后您在views表上保留左联接,该表有5条记录所有这些记录都在2012/12/28天。所以这一天你有5条记录。

答案 2 :(得分:0)

将聚合放置在子查询中,例如:

select 
    dates.d as day,
    coalesce(v.count, 0) as views_count,
    coalesce(i.count, 0) as items_count
from generate_series('2018-12-26'::date, '2018-12-30', '1 day' ) as dates(d)
left join (
    select created_at::date as day, count(*)
    from views 
    group by day
    ) as v on v.day = dates.d
left join (
    select created_at::date as day, count(*)
    from items 
    group by day
    ) as i on i.day = dates.d
order by day desc

          day           | views_count | items_count 
------------------------+-------------+-------------
 2018-12-30 00:00:00+01 |           0 |           0
 2018-12-29 00:00:00+01 |           0 |           0
 2018-12-28 00:00:00+01 |           5 |           1
 2018-12-27 00:00:00+01 |           0 |           0
 2018-12-26 00:00:00+01 |           0 |           0
(5 rows)