如何按日期小时进行 SQL 分组 [关闭]

Posted

技术标签:

【中文标题】如何按日期小时进行 SQL 分组 [关闭]【英文标题】:How to SQL Group by Date Hour [closed] 【发布时间】:2021-01-14 08:40:52 【问题描述】:

您好,我有一张下表。

ID  Created Date                Deposit Money

18  2021-01-14 17:19:10.932030  16862895
17  2021-01-14 13:18:13.944762  625000
16  2021-01-14 12:19:55.565888  616000
15  2021-01-14 11:19:10.932030  16862895
14  2021-01-14 10:18:13.944762  625000
13  2021-01-14 09:19:55.565888  616000
12  2021-01-14 09:01:10.932030  16862895
11  2021-01-14 08:02:13.944000  625000
10  2021-01-14 08:01:55.565888  616000
9   2021-01-14 07:19:10.932030  16862895
8   2021-01-14 07:19:10.932030  16862895
7   2021-01-14 07:18:13.944762  625000
6   2021-01-14 07:18:13.944762  625000
5   2021-01-14 06:19:55.565888  616000
4   2021-01-14 06:19:55.565888  616000
3   2021-01-13 21:32:46.538236  19245
2   2021-01-13 19:33:30.693695  25560
1   2021-01-13 18:13:30.693695  588820

我想要结果。

2021-01-13 16:00 ~ 2021-01-14 09:59  sum(deposit_money)
2021-01-14 10:00 ~ 2021-01-14 12:59  sum(deposit_money)
2021-01-14 13:00 ~ 2021-01-14 15:59  sum(deposit_money)
2021-01-14 16:00 ~ 2021-01-15 09:59  sum(deposit_money)

.....

yesterday 16:00 ~ today 10:00
today 10:00 ~ today 13:00
today 13:00 ~ today 16:00
today 16:00 ~ tommorrow 10:00 

我不知道如何设置分组依据。 如果您能自行回复,谢谢

【问题讨论】:

欢迎来到 Stack Overflow!请访问help center,以tour 了解内容和How to Ask。做一些研究,搜索关于SO的相关主题;如果您遇到困难,请发布您的尝试minimal reproducible example 【参考方案1】:

您可以构建一个子查询,其中包含所需时间的时间表,如下例所示:

SELECT p.start_from, p.end_to, SUM(t.deposit) AS total 
FROM deposits t
JOIN (
    SELECT
        TIMESTAMPADD(HOUR, 16, DATE_SUB(CURDATE(), INTERVAL 1 DAY)) AS start_from,
        TIMESTAMPADD(SECOND, 10 * 60 * 60 - 1, CURDATE()) AS end_to
    UNION ALL SELECT 
        TIMESTAMPADD(HOUR, 10, CURDATE()),
        TIMESTAMPADD(SECOND, 13 * 60 * 60 - 1, CURDATE())
    UNION ALL SELECT 
        TIMESTAMPADD(HOUR, 13, CURDATE()),
        TIMESTAMPADD(SECOND, 16 * 60 * 60 - 1, CURDATE())
    UNION ALL SELECT 
        TIMESTAMPADD(HOUR, 16, CURDATE()),
        TIMESTAMPADD(SECOND, 10 * 60 * 60 - 1, DATE_ADD(CURDATE(), INTERVAL 1 DAY))

) p ON created BETWEEN start_from AND end_to
GROUP BY p.start_from, p.end_to

db-fiddle

【讨论】:

【参考方案2】:

我假设你真的想要所有日期都这样,而不仅仅是当前日期。

您可以使用case 表达式指定句点的开始:

select t.*,
       (case when time(created_date) < '10:00:00'
             then (date(created_date) - interval 1 day) + interval 16 hour
             when  time(created_date) < '13:00:00'
             then date(created_date) + interval 10 hour
             when time(created_date) < '16:00:00'
             then date(created_date) + interval 13 hour
             else date(created_date) + interval 16 hour
        end)
from t;

然后您可以轻松地将其合并到聚合中:

select (case when time(created_date) < '10:00:00'
             then (date(created_date) - interval 1 day) + interval 16 hour
             when  time(created_date) < '13:00:00'
             then date(created_date) + interval 10 hour
             when time(created_date) < '16:00:00'
             then date(created_date) + interval 13 hour
             else date(created_date) + interval 16 hour
        end) as period,
       count(*)
from t
group by period
order by min(created_date);

注意:这仅处理句点开始。这似乎足以满足您想要的结果。

如果您只想在一段时间内这样做,您可以包含一个where 子句,过滤您想要的时间段内的行。

【讨论】:

以上是关于如何按日期小时进行 SQL 分组 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何创建 SQL 查询来计算按日期分组和连接的项目? [关闭]

如何按特定日期范围(例如小时、日、月)对数据进行分组?

在 SQL/Impala 中按特定的分钟数对日期时间进行分组

如何按小时对 HKStatistics 进行分组?

在 SQL 中查找按日期分组的集合中的平均最低项

如何使用 sql 和按日期分组显示指标在日期上的累积增长?