postgresql 不存在订单时的SQL日期计数

slhcrj9b  于 2023-06-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(114)

我正试图计算在连接中没有出现的行。我希望没有订单的天数计数为0。
希望此查询在没有日期的日期旁边返回0,并且不返回null。

SELECT           days.date,
                 COALESCE(Count(service_orders.id)::int) AS count
FROM             (
                        SELECT To_char( Date_trunc('day', (CURRENT_DATE + offs)), 'YYYY-MM-DD' )            AS date,
                               trim(both ' ' FROM to_char(date_trunc('day', (CURRENT_DATE + offs)), 'day')) AS day
                        FROM   generate_series(0, 60, 1)                                                    AS offs ) days
RIGHT OUTER JOIN
                 (
                           SELECT    service_order.id,
                                     to_char( date_trunc('day', service_order.date), 'YYYY-MM-DD' ) service_order_day
                           FROM      service_order
                           LEFT JOIN order_
                           ON        service_order.order_id = order_.id) service_orders
ON               days.date = service_orders.service_order_day
GROUP BY         days.date
ORDER BY         days.date ASC;
2023-06-22  6
2023-06-23  5
NULL        15312

我不想要null!我也希望有计数为0的天数。
所以我想要的是

2023-06-22  6
2023-06-23  5
2023-06-24  0
2023-06-25  0
...
qyyhg6bp

qyyhg6bp1#

我理解您的问题,您需要未来60天内每天的服务订单数量(包括没有任何订单的天数)。
你似乎把事情搞得太复杂了:

  • 你可以直接在日期上使用generate_series(不需要一系列数字的中间步骤)
  • 下一步是连接服务订单表,以计算每个日期的行数;这可以通过横向连接和聚合有效地完成(注意,我们不需要将日期来回转换为字符串,我们可以直接过滤半开间隔)
  • 据我所知,表order_在查询中是多余的

这不是你想要的吗

select d.dt, so.cnt
from generate_series(current_date, current_date + interval '60 day', interval '1 day') as d(dt)
cross join lateral (
    select count(*) cnt
    from service_order so
    where so.date >= d.dt and so.date < d.dt + interval '1 day'
) so

我们也可以使用left join和外部聚合:

select d.dt, count(so.id) cnt
from generate_series(current_date, current_date + interval '60 day', interval '1 day') as d(dt)
left join service_order so on so.date >= d.dt and so.date < d.dt + interval '1 day'
group by d.dt

相关问题