SQL Server 按月、日和小时划分多个分区
Posted
技术标签:
【中文标题】SQL Server 按月、日和小时划分多个分区【英文标题】:SQL Server multiple partitions by month, day and hour 【发布时间】:2020-06-15 17:03:17 【问题描述】:在 SQL Server 中,我有一个如下表:
processName initDateTime
processA 2020-06-15 13:31:15.330
processB 2020-06-20 10:00:30.000
processA 2020-06-20 13:31:15.330
...
and so on
我需要按 processName 分组,对于每个 processName,我需要按月 (#byMonth)、日 (#byDay) 和小时 (#byHour) 获取记录数。
最好的方法是什么?下面的东西? SQL 查询是什么?
可能的结果:
processName Month Day Hour #byMonth #byDay #byHour #total(by process)
processA January 15 17 4 3 2 7
processA January 15 20 4 3 1 7
processA January 20 05 4 2 3 7
processA January 20 13 4 2 1 7
processA March 04 05 3 2 3 7
processA March 04 17 3 2 2 7
processA March 15 05 3 3 3 7
...and so on for the rest of processes name
【问题讨论】:
【参考方案1】:我认为你想要聚合和窗口函数:
select
processName,
month(initDateTime),
day(initDateTime),
datepart(hour, initDateTime),
sum(count(*)) over(partition by processName, year(initDateTime), month(initDateTime)) byMonth,
sum(count(*)) over(partition by processName, year(initDateTime), month(initDateTime), day(initDateTime)) byDay,
count(*) byHour
from mytable
group by
processName,
year(initDateTime),
month(initDateTime),
day(initDateTime),
datepart(hour, initDateTime)
【讨论】:
正是我想要的。只有一件事,你忘了在 byDay 之前加上括号。【参考方案2】:只要有可能,我喜欢将日期作为日期返回给调用者,以便他们也可以将它们作为日期处理,例如排序、转换为本地时间,甚至确保显示的语言是相关的。所以如果是我,我会这样做:
-- sample data
CREATE TABLE #T (processName VARCHAR(50), initDateTime DATETIME)
INSERT #T (processName, initDateTime)
VALUES
('processA', '2020-06-15 13:31:15.330'),
('processB', '2020-06-20 10:00:30.000'),
('processA', '2020-06-20 13:31:15.330')
SELECT t.processName,
i.InitHour,
ByMonth = SUM(COUNT(*)) OVER(PARTITION BY i.InitMonth),
ByDay = SUM(COUNT(*)) OVER(PARTITION BY i.InitDay),
ByHour = COUNT(*)
FROM #T AS t
CROSS APPLY
( SELECT InitHour = DATEADD(HOUR, DATEDIFF(HOUR, 0, initDateTime), 0),
InitDay = DATEADD(DAY, DATEDIFF(DAY, 0, initDateTime), 0),
InitMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, initDateTime), 0)
) AS i
GROUP BY t.processName, i.InitHour, i.InitDay, i.InitMonth;
返回:
processName InitHour ByMonth ByDay ByHour
--------------------------------------------------------------
processA 2020-06-15 13:00:00 3 1 1
processA 2020-06-20 13:00:00 3 2 1
processB 2020-06-20 10:00:00 3 2 1
如果你需要SQL中的日期、月份名称等,你可以使用DATEPART
或DATENAME
来获取这些,但是如上所述,这在表示层中处理得更好,所以你可以处理语言环境,或特定的用户设置。
【讨论】:
以上是关于SQL Server 按月、日和小时划分多个分区的主要内容,如果未能解决你的问题,请参考以下文章