sql server按月、日和小时划分多个分区

np8igboo  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(355)

在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
nfeuvbwi

nfeuvbwi1#

我认为您需要聚合和窗口函数:

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)
ldxq2e6h

ldxq2e6h2#

在可能的情况下,我喜欢将日期作为日期返回给调用者,这样他们也可以将日期作为排序、转换为本地时间,甚至确保显示的语言是相关的。所以如果是我,我会做以下事情:

-- 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 ,但如上所述,这在表示层中处理得更好,因此您可以处理区域设置或特定的用户设置。

相关问题