【问题标题】:Query to retrieve count per hour and zero if none查询以每小时检索计数,如果没有则为零
【发布时间】:2018-07-26 09:48:53
【问题描述】:

我正在尝试所有方法,但到目前为止我都没有成功。

我通过以下方式获取我的数据。我正在使用 postGreSQL

order_id |      create_date
    -----+--------------------
    6000 | 2013-05-09 11:53:04
    6001 | 2013-05-09 12:58:00
    6002 | 2013-05-09 13:01:08
    6003 | 2013-05-09 13:01:32
    6004 | 2013-05-09 14:05:06
    6005 | 2013-05-09 14:06:25
    6006 | 2013-05-09 14:59:58
    6007 | 2013-05-09 19:00:07

我需要一个查询来生成所有 24 小时内每小时的订单数。如果一个小时内没有订单,则查询输出默认为零。下面应该是输出格式。

    orders |      hour
    -----+--------------------
    0    | 00:00
    0    | 01:00
    0    | 02:00
    0    | 03:00
    0    | 04:00
    0    | 05:00
    0    | 06:00
    0    | 07:00
    0    | 08:00
    0    | 09:00
    0    | 10:00
    1    | 11:00
    1    | 12:00
    2    | 13:00
    3    | 14:00
    0    | 15:00
    0    | 16:00
    0    | 17:00
    0    | 18:00
    1    | 19:00
    0    | 20:00
    0    | 21:00
    0    | 22:00
    0    | 23:00

有可能吗?以下是我当前的查询。当然,它并没有以我想要的方式提供输出。

select count(order_id) as orders, date_trunc('hour', create_date) as hr from order_table where date_trunc('day', create_date)='2013-05-09' GROUP BY date_trunc('hour', create_date);

【问题讨论】:

  • 您在哪个 DBMS 上工作? MySQL 还是 PostgreSQL?另外,能否请您发布表架构?
  • 我正在使用 PostgreSQL
  • 这可能会有所帮助。 plumislandmedia.net/mysql/…
  • @O.Jones 不是mysql,是postgresql
  • 我在它还有一个 MySQL 标签的时候关闭了这个问题。我已经提名它重新开放。其他人也可以这样做。

标签: sql postgresql


【解决方案1】:

您需要生成小时数。这是使用generate_series()的一种方法:

select '00:00'::time + g.h * interval '1 hour',
       count(order_id) as orders
from generate_series(0, 23, 1) g(h) left join
     order_table ot
     on extract(hour from create_date) = g.h and
        date_trunc('day', create_date) = '2013-05-09'
group by g.h
order by g.h;

或者:

select g.dte, count(order_id) as orders
from generate_series('2013-05-09'::timestamp, '2013-05-09 23:00:00'::timestamp, interval '1 hour') g(dte) left join
     order_table ot
     on g.dte = date_trunc('hour', create_date) 
group by g.dte
order by g.dte;

【讨论】:

  • 在第一个查询输出中,小时列的输出格式为“01:00:00”。我们如何将其更改为“01:00”?
  • 第一个答案为我提供了问题中的确切内容。
【解决方案2】:

我还能回答吗?测试,测试,哦,是的,它有效。好的,我认为您查询中的问题是您的比较错误:date_trunc('day', create_date)='2013-05-09' 应该是:date_trunc('day', create_date)='2013-05-09 00:00:00'。像这样:

SELECT COUNT(order_id) as orders, 
       date_trunc('hour',create_date) as hr 
FROM order_table 
WHERE date_trunc('day', create_date) = '2013-05-09 00:00:00' 
GROUP BY date_trunc('hour',create_date);

然而,这不会返回零计数,但其他人已经解决了这个问题。

【讨论】:

    【解决方案3】:

    使用数字 CTE(Postgresql 示例):

    with Nums(NN) as
    (
    values(0)
    union all
    select NN+1
    where NN <23
    )
    select NN as the_hour, count(order_id) as orders
    from Nums
    left join order_table
    on date_part('hour',create_date) = NN
    group by NN
    

    【讨论】:

    • 它给了我一个错误,比如“列“nn”不存在”。我需要在每个地方都用日期替换 NN 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多