SQL - 在日期桶中放置值
Posted
技术标签:
【中文标题】SQL - 在日期桶中放置值【英文标题】:SQL - placing values in date bucket 【发布时间】:2021-12-14 10:51:31 【问题描述】:作为一个 SQL 新手确实在为此苦苦挣扎,所以我需要根据一天中的时间将 is_registered 列中的值放入每小时存储桶中。下面是一个小样本
creation date | is_registered |
---|---|
2021-10-28 00:03:12.240 | 1 |
2021-10-28 00:09:16.221 | 1 |
2021-10-28 00:12:23.234 | 1 |
2021-10-29 00:03:19.240 | 1 |
2021-10-29 00:48:12:190 | 1 |
2021-10-29 01:09:36:129 | 1 |
2021-10-29 01:29:29:120 | 1 |
我想要达到的结果(使用完整的数据集)如下(一天中每个小时的存储桶
Date | Hour Bucket | Total in each bucket |
---|---|---|
2021-10-28 | 00:00-01:00 | 289 |
2021-10-28 | 01:00-02:00 | 876 |
-------- | -------------- | ------------- |
2021-10-29 | 00:00-01:00 | 190 |
2021-10-29 | 01:00-02:00 | 309 |
等等。
希望提供足够的信息,任何帮助将不胜感激,谢谢
【问题讨论】:
因此,如果一行在 1:00 被“注册”,它是否计入前 2 个输出行?将 1 小时视为从 0:0:0 到 1:0:0(61 分钟)是一个常见的错误。 对不起,应该更清楚,如果在 12:59 注册,它将下降到 12:00 所以 00:00-01:00 reg at 01:00:19 将是 01:00- 02:00 Refer to this 【参考方案1】:试试下面的方法
--Create table script
CREATE TABLE [dbo].[Table_4](
[creationdate] [datetime] NULL,
[isreg] [int] NULL
) ON [PRIMARY]
GO
--Sample data
insert into table_4 values (getdate(),1)
insert into table_4 values (getdate()-1,1)
go
-- query
WITH report(N) AS(
SELECT TOP(23) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM sys.columns
)
,hourly(creationdate) AS(
SELECT DATEADD(HOUR, t.N, d.creationdate)
FROM report t
CROSS JOIN(
SELECT DISTINCT DATEADD(DD, DATEDIFF(DD, 0, creationdate), 0) AS creationdate FROM table_4
) d
)
SELECT
convert(date, h.creationdate) as [Creation date],
convert(varchar(5), DATEPART(HOUR, h.creationdate)-1)+ ' - ' + convert(varchar(5),DATEPART(HOUR, h.creationdate)) as [Hour Bucket],
[Total in each bucket] = ISNULL(t.isreg, 0)
FROM hourly h
LEFT JOIN(
SELECT
creationdate = DATEADD(HOUR, DATEPART(HOUR, creationdate) ,DATEADD(DD, DATEDIFF(DD, 0, creationdate), 0)),
isreg = COUNT(*)
FROM table_4
GROUP BY DATEADD(DD, DATEDIFF(DD, 0, creationdate), 0), DATEPART(HOUR, creationdate)
)t
ON t.creationdate = h.creationdate
order by h.creationdate
Reference link
【讨论】:
谢谢 Malvik,为什么需要创建表和插入示例数据? 我已经用我的示例数据添加了答案。如果您具有相同的结构,则不需要创建该表并插入示例数据。【参考方案2】:使用这个 tvf 可能更易于维护: DateRange TVF
WITH Ranges
AS
(
SELECT [Value] AS date_from
,LEAD([Value]) OVER (ORDER BY [Value]) AS date_to
,CAST([Value] AS date) AS [Date]
,CONVERT(char(5), [Value], 14) + '-'
+ CONVERT(char(5), LEAD([Value]) OVER (ORDER BY [Value]), 14) AS Hour_Bucket
FROM dbo.DateRange('2021-10-28', '2021-10-30', 'hh', 1)
)
SELECT R.[Date], R.Hour_Bucket
,COUNT(T.is_registered) AS Total_Registered
FROM Ranges R
LEFT JOIN YourTable T
ON T.creation_date >= R.date_from
AND T.creation_date < R.date_to
AND T.is_registered = 1
WHERE R.date_to IS NOT NULL
GROUP BY R.[Date], R.Hour_Bucket
ORDER BY [Date], Hour_Bucket;
【讨论】:
以上是关于SQL - 在日期桶中放置值的主要内容,如果未能解决你的问题,请参考以下文章