如何在表格中按每天的每个小时分组数据?

huangapple go评论89阅读模式
英文:

How I can group the data for each hour of each day in a table?

问题

大家好!
请告诉我如何在表格中为每天的每个小时分组数据?
我有一个名为 sales 的表。该表包含以下数据:
sale_id - 销售的ID。
sale_start - 销售流程开始的时间(时间戳)。
sale_canceled - 销售取消的时间(时间戳)。
sale_completed - 销售完成的时间(时间戳)。

...
我需要计算每周每个时间小时内有多少销售和可用销售数量。

总的来说,现在我有一个 PostgreSQL 查询,当我使用 "LIMIT" 时它能够工作。否则,请求会崩溃。
PostgreSQL 查询:

  1. WITH s AS (SELECT date_trunc('hour', '2022-04-22'::date) - generate_series(0, 24 * 7) * interval '1 hour' AS h_slot
  2. FROM sales),
  3. dt AS (SELECT DATE_TRUNC('hour', "sale_start") AS sale_start,
  4. DATE_TRUNC('hour', "sale_canceled") AS sale_canceled,
  5. DATE_TRUNC('hour', "sale_completed") AS sale_completed,
  6. FROM sales
  7. WHERE "sale_start" >= '2022-08-10'::date - INTERVAL '1 week'
  8. AND "sale_start" <= '2023-08-10'),
  9. SELECT s.h_slot,
  10. COUNT(*) FILTER (WHERE dt.sale_completed = s.h_slot) AS completed_count,
  11. COUNT(*) FILTER (WHERE s.h_slot >= dt.sale_start
  12. AND s.h_slot <= dt.sale_canceled) AS available_count
  13. FROM s CROSS JOIN dt
  14. GROUP BY s.h_slot
  15. ORDER BY s.h_slot
英文:

Hi everybody!
Please tell me how I can group the data for each hour of each day in a table?
I have a table with the name sales. This table contains the data:
sale_id - id of the sale.
sale_start - when the sale process was started (timestamp).
sale_canceled - when the sale was canceled(timestamp).
sale_completed - when the sale was made (timestamp).
table

...
I need to calculate how many sales have been made and are available at every hour of time during the week.

In general, now I have a postgresql-query and it works when I use "LIMIT". Otherwise, the request crashes.
Postgresql-query:

  1. WITH s AS (SELECT date_trunc(&#39;hour&#39;, &#39;2022-04-22&#39;::date) - generate_series(0, 24 * 7) * interval &#39;1 hour&#39; AS h_slot
  2. FROM sales),
  3. dt AS (SELECT DATE_TRUNC(&#39;hour&#39;, &quot;sale_start&quot;) AS sale_start,
  4. DATE_TRUNC(&#39;hour&#39;, &quot;sale_canceled&quot;) AS sale_canceled,
  5. DATE_TRUNC(&#39;hour&#39;, &quot;sale_completed&quot;) AS sale_completed,
  6. FROM sales
  7. WHERE &quot;sale_start&quot; &gt;= &#39;2022-08-10&#39;::date - INTERVAL &#39;1 week&#39;
  8. AND &quot;sale_start&quot; &lt;= &#39;2023-08-10&#39;),
  9. SELECT s.h_slot,
  10. COUNT(*) FILTER (WHERE dt.sale_completed = s.h_slot) AS completed_count,
  11. COUNT(*) FILTER (WHERE s.h_slot &gt;= dt.sale_start
  12. AND s.h_slot &lt;= dt.sale_canceled) AS available_count
  13. FROM s CROSS JOIN dt
  14. GROUP BY s.h_slot
  15. ORDER BY s.h_slot

答案1

得分: 1

请注意以下片段:

  1. WITH s AS (
  2. SELECT date_trunc('hour', '2022-04-22'::date)
  3. - generate_series(0, 24 * 7) * interval '1 hour' AS h_slot
  4. FROM sales
  5. )

在这里,你生成了一个大小为7 * 24 *(sales表中记录数)的系列。

然后与dt (sales)进行“cross join”。

总记录数为7 * 24 (sales表中记录数)(sales中销售周的时间间隔的记录数)。

首先,移除“FROM Sales”。

这可能会解决你的问题。

  1. WITH s AS (
  2. SELECT date_trunc('hour', '2022-04-22'::date)
  3. - generate_series(0, 24 * 7) * interval '1 hour' AS h_slot
  4. )

例如,尝试这个:

  1. WITH s AS (
  2. SELECT date_trunc('hour', '2022-8-10'::date) - generate_series(0, 24 * 7) * interval '1 hour' AS h_slot
  3. )
  4. , avlbl AS (
  5. SELECT DATE_TRUNC('hour', "sale_start") intrvl
  6. ,count(*) as cnt_available
  7. FROM sales
  8. WHERE "sale_start" >= '2022-08-10'::date - INTERVAL '1 week'
  9. AND "sale_start" <= '2023-08-10'
  10. GROUP BY DATE_TRUNC('hour', "sale_start")
  11. )
  12. , dtgr AS (
  13. SELECT COALESCE(DATE_TRUNC('hour', "sale_cancelled")
  14. ,DATE_TRUNC('hour', "sale_completed")) dthour
  15. ,count(sale_cancelled) cnt_cancelled
  16. ,count(sale_completed) cnt_completed
  17. FROM sales
  18. WHERE "sale_start" >= '2022-08-10'::date - INTERVAL '1 week'
  19. AND "sale_start" <= '2023-08-10'
  20. GROUP BY COALESCE(DATE_TRUNC('hour', "sale_cancelled")
  21. ,DATE_TRUNC('hour', "sale_completed"))
  22. )
  23. SELECT *
  24. FROM s
  25. LEFT JOIN dtgr d ON d.dthour = s.h_slot
  26. LEFT JOIN avlbl a ON a.intrvl = s.h_slot
  27. ORDER BY s.h_slot
英文:

Pay attention to the fragment:

  1. WITH s AS (
  2. SELECT date_trunc(&#39;hour&#39;, &#39;2022-04-22&#39;::date)
  3. - generate_series(0, 24 * 7) * interval &#39;1 hour&#39; AS h_slot
  4. FROM sales
  5. )

There you generate series of size= 7 * 24 *(count of records in table sales).

Then cross join with dt (sales).
Total number of records is
7 * 24 *(count of records in table sales) * (count of records in interval (week) of sales)

First, remove FROM Sales.
This may solve your problem.

  1. WITH s AS (
  2. SELECT date_trunc(&#39;hour&#39;, &#39;2022-04-22&#39;::date)
  3. - generate_series(0, 24 * 7) * interval &#39;1 hour&#39; AS h_slot
  4. )

For example, try this.

  1. WITH s AS (SELECT date_trunc(&#39;hour&#39;, &#39;2022-8-10&#39;::date) - generate_series(0, 24 * 7) * interval &#39;1 hour&#39; AS h_slot
  2. )
  3. ,avlbl AS (
  4. SELECT DATE_TRUNC(&#39;hour&#39;, &quot;sale_start&quot;) intrvl
  5. ,count(*) as cnt_availible
  6. FROM sales
  7. WHERE &quot;sale_start&quot; &gt;= &#39;2022-08-10&#39;::date - INTERVAL &#39;1 week&#39;
  8. AND &quot;sale_start&quot; &lt;= &#39;2023-08-10&#39;
  9. group by DATE_TRUNC(&#39;hour&#39;, &quot;sale_start&quot;)
  10. )
  11. ,dtgr AS (
  12. SELECT coalesce(DATE_TRUNC(&#39;hour&#39;, &quot;sale_cancelled&quot;)
  13. ,DATE_TRUNC(&#39;hour&#39;, &quot;sale_completed&quot;)) dthour
  14. ,count(sale_cancelled) cnt_cancelled
  15. ,count(sale_completed) cnt_completed
  16. FROM sales
  17. WHERE &quot;sale_start&quot; &gt;= &#39;2022-08-10&#39;::date - INTERVAL &#39;1 week&#39;
  18. AND &quot;sale_start&quot; &lt;= &#39;2023-08-10&#39;
  19. group by coalesce(DATE_TRUNC(&#39;hour&#39;, &quot;sale_cancelled&quot;)
  20. ,DATE_TRUNC(&#39;hour&#39;, &quot;sale_completed&quot;))
  21. )
  22. SELECT *
  23. FROM s
  24. left JOIN dtgr d on d.dthour=s.h_slot
  25. left join avlbl a on a.intrvl=s.h_slot
  26. ORDER BY s.h_slot

huangapple
  • 本文由 发表于 2023年7月31日 21:12:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803992.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定