Really struggling with this as a SQL newb, so i need to place values from the is_registered column into hourly buckets based on the time of day they were created. The below is a small sample
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 |
The result I would like to acheive (with the full dataset) is the following(buckets for each hour of the day
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 |
And so on.
Hope thats as enough information provided, any help would be greatly appreciated, thank you
CodePudding user response:
Try following way
--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
CodePudding user response:
Using this tvf may be more maintainable: 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;