【问题标题】:Postgresql Serial Daily Count of RecordsPostgresql 串行每日记录计数
【发布时间】:2020-08-21 22:11:55
【问题描述】:

我正在尝试获取从 1 月 1 日至今的记录总数,而不是跳过日期并为没有记录的日期返回 0。

我尝试了以下方法:orders 是一个示例表,orderdate 是一个时间戳列

with days as (
  select generate_series(
    date_trunc('day','2020-01-01'::timestamp),
    date_trunc('day', now()),
    '1 day'::interval
  ) as day
)
select
  days.day,
  count(orders.id)
from days
left outer join orders on date_trunc('day', orders.orderdate) = days.day
where orders.orders_type='C'
group by 1

问题是日期被跳过。 但如果我执行:

select generate_series(
    date_trunc('day','2020-01-01'::timestamp),
    date_trunc('day', now()),
    '1 day'::interval
  )

我得到了正确的系列,没有跳过任何日期。

【问题讨论】:

    标签: sql postgresql datetime left-join recursive-query


    【解决方案1】:

    where 条件应该属于left joinon 子句,即:

    from days
    left outer join orders on date_trunc('day', orders.orderdate) = days.day
    where orders.orders_type='C'
    

    应该写成:

    from days
    left outer join orders 
        on  date_trunc('day', orders.orderdate) = days.day
        and orders.orders_type='C'
    

    注意事项:

    • 这里其实不需要cte,可以直接把generate_series()放在from子句中

    • 日期连接条件可以优化为避免date_trunc()的索引友好表达式

    • 表别名使查询更易于读写

    您可以将查询编写为:

    select d.day, count(o.id)
    from generate_series(date '2020-01-01', now(), '1 day') as d(day)
    left outer join orders o
        on  o.orderdate >= d.day
        and o.orderdate <  d.day + '1 day'::interval
        and o.orders_type='C'
    group by d.day
    

    【讨论】:

    • 感谢@GMB,两种解决方案都有效。尽管 cte 似乎要快得多。我了解在日期加入时利用任何索引,但此列上没有索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 2021-05-25
    • 1970-01-01
    • 2018-02-06
    • 2015-01-31
    • 1970-01-01
    相关资源
    最近更新 更多