在postgresql中获取特定时间段内的每日查询结果

发布于 2025-01-14 07:16:43 字数 996 浏览 1 评论 0原文

我在 postgresql 数据库中有一个名为 order 的表。所有订单相关信息都存储在其中。现在,如果订单被拒绝,则某些订单行将从订单表中移出并存储在rejected_orders 表中。因此,计数函数无法提供正确的订单数。

现在,如果我想获取某一天的订单请求数量。我必须减去当天最后一个订单和当天第一个订单之间的 ID 号。下面,我查询了 2022 年 3 月 1 日的总请求数。 遗憾的是,前任员工忘记在数据库中正确保存时区。数据以UTC+00时区保存在数据库中,获取的数据需要在GMT+06时区。

select 
(select id from orders
 where created_at<'2022-03-02 00:00:00+06' 
order by created_at desc limit 1
) 
- 
(select id from orders 
where created_at>='2022-03-01 00:00:00+06' 
order by created_at limit 1
) as march_1st;



march_1st 
-----------
185

现在, 如果我想获取特定时间段内每天的总请求数(假设为 2021 年 3 月)。如何在一个 sql 查询中做到这一点,而不必每天编写一个查询?

总结一下,

total_request_per_day = 当日最后一个订单的 ID - 第一个订单的 ID 当天的顺序。

如何根据该逻辑编写查询,该逻辑将为我提供特定月份中每一天的total_request_per_day。 像这样,

|Date       | total requests|
|01-03-2022 | 187           |
|02-03-2022 | 202           |
|03-03-2022 | 227           |
................
................

i have a table in postgresql database called orders. where all the order related informations are stored. now, if an order gets rejected that certain order row gets moved from the orders table and gets stored in the rejected_orders table. As a result, the count function does not provide the correct number of orders.

Now, if I want to get the number of order request(s) in a certain day. I have to subtract the id numbers between the last order of the day and first order of the day. Below, i have the query for number total request for March 1st, 2022. Sadly, the previous employe forgot to save the timezone correctly in the database. Data is saved in the DB at UTC+00 timezone, Fetched data needs to be in GMT+06 timezone.

select 
(select id from orders
 where created_at<'2022-03-02 00:00:00+06' 
order by created_at desc limit 1
) 
- 
(select id from orders 
where created_at>='2022-03-01 00:00:00+06' 
order by created_at limit 1
) as march_1st;



march_1st 
-----------
185

Now,
If I want to get total request per day for certain time period(let's for month March, 2021). how can I do that in one sql query without having to write one query per day ?

To wrap-up,

total_request_per_day = id of last order of the day - id of first
order of the day.

How do I write a query based on that logic that would give me total_request_per_day for every day in a certain month.
like this,

|Date       | total requests|
|01-03-2022 | 187           |
|02-03-2022 | 202           |
|03-03-2022 | 227           |
................
................

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

轮廓§ 2025-01-21 07:16:43

恕我直言,使用 id 数字来确定一段时间内的行数是不正确的。删除行会在 id 编号序列中留下间隙;它们不是为此目的而设计的。

这是 date_trunc()COUNT(*)GROUP BY 的工作。

date_trunc('day',created_at) 函数将任意时间戳转换为当天的午夜。例如,它将“2022-03-02 16:41:00转换为2022-03-02 00:00:00”。使用它我们可以这样编写查询。

SELECT COUNT(*) order_count, 
       date_trunc('day', created_at) day
  FROM orders
 WHERE created_at >= date_trunc('day', NOW()) - INTERVAL '7 day'
   AND created_at <  date_trunc('day', NOW())
 GROUP BY date_trunc('day', created_at)

此查询给出过去 7 天内每天的订单数。

您花在学习如何使用这样的 SQL 数据运算上的每一分钟都将在您节省的工作时间中得到回报。

With respect, using id numbers to determine numbers of rows in a time period is incorrect. DELETEing rows leaves gaps in id number sequences; they are not designed for this purpose.

This is a job for date_trunc(), COUNT(*), and GROUP BY.

The date_trunc('day', created_at) function turns an arbitrary timestamp into midnight on its day. For example, it turns ``2022-03-02 16:41:00into2022-03-02 00:00:00`. Using that we can write the query this way.

SELECT COUNT(*) order_count, 
       date_trunc('day', created_at) day
  FROM orders
 WHERE created_at >= date_trunc('day', NOW()) - INTERVAL '7 day'
   AND created_at <  date_trunc('day', NOW())
 GROUP BY date_trunc('day', created_at)

This query gives the number of orders on each day in the last 7 days.

Every minute you spend learning how to use SQL data arithmetic like this will pay off in hours saved in your work.

枉心 2025-01-21 07:16:43

试试这个:

SELECT  d.ref_date :: date AS "date"
     , count(*) AS "total requests"
  FROM generate_series('20220301' :: timestamp, '20220331' :: timestamp, '1 day') AS d(ref_date)
  LEFT JOIN orders
    ON date_trunc('day', d.ref_date) = date_trunc('day', created_at)
 GROUP BY d.ref_date
  • generate_series() 生成您可以在其中的参考日期列表
    想要统计订单数量

  • 然后,您只需将参考日期与年/月/日的 created_at 日期进行比较即可加入 orders 表。 LEFT JOIN 允许您选择没有现有订单的参考日。

  • 最后,您通过按参考日分组来计算每天的订单数。

Try this :

SELECT  d.ref_date :: date AS "date"
     , count(*) AS "total requests"
  FROM generate_series('20220301' :: timestamp, '20220331' :: timestamp, '1 day') AS d(ref_date)
  LEFT JOIN orders
    ON date_trunc('day', d.ref_date) = date_trunc('day', created_at)
 GROUP BY d.ref_date
  • generate_series() generates the list of reference days where you
    want to count the number of orders

  • Then you join with the orders table by comparing the reference date with the created_at date on year/month/day only. LEFT JOIN allows you to select reference days with no existing order.

  • Finally you count the number of orders per day by grouping by reference day.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文