【问题标题】:How to group by Date and Hour :00:00 in SQL Server 2008如何在 SQL Server 2008 中按日期和小时 :00:00 分组
【发布时间】:2017-11-25 06:49:01
【问题描述】:

我想创建每小时报告,这个查询运行良好。

SELECT 
    FORMAT(PingLogDate,'yyyy-MM-dd-HH:00:00') AS CalculatedTime, 
    COUNT(PingLogID) AS PingCount
FROM
    tbl_PingLog
GROUP BY 
    FORMAT(PingLogDate,'yyyy-MM-dd-HH:00:00')
ORDER BY 
    FORMAT(PingLogDate,'yyyy-MM-dd-HH:00:00')

但我支持 SQL Server 2008 并且Format 是 SQL Server 2012 中的新功能,所以我尝试了这段代码

SELECT 
    CAST(PingLogDate AS date) AS CalculatedDate, 
    DATEPART(hour, PingLogDate) AS CalculatedTime, 
    COUNT(PingLogID) AS PingCount
FROM
    tbl_PingLog
GROUP BY 
    CAST(PingLogDate AS date), DATEPART(hour, PingLogDate)
ORDER BY 
    CAST(PingLogDate AS date), DATEPART(hour, PingLogDate)

问题是不想为日期和小时设置 2 列,例如

第一个查询的结果是

CalculatedTime      | PingCount
--------------------+-----------
2017-11-07-12:00:00 | 359
2017-11-07-13:00:00 | 359
2017-11-07-14:00:00 | 350

第二次查询的结果是

CalculatedDate |CalculatedTime | PingCount
---------------+---------------+----------
2017-11-07     |12             | 359
2017-11-07     |13             | 359
2017-11-07     |14             | 350

我不想要第二个。我要第一个。如何使用 SQL Server 2008 支持的工具来做到这一点。

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql


    【解决方案1】:

    您可以使用CONVERTdatetime 列转换为yyyy-mm-dd hh:mi:ss(24h) 格式,然后将空格替换为-

    类似这样的:

    SELECT REPLACE(CONVERT(VARCHAR(32), PingLogDate, 120), ' ', '-') AS CalculatedTime, 
           COUNT(PingLogID) AS PingCount
    FROM tbl_PingLog
    GROUP BY REPLACE(CONVERT(VARCHAR(32), PingLogDate, 120), ' ', '-')
    ORDER BY REPLACE(CONVERT(VARCHAR(32), PingLogDate, 120), ' ', '-')
    

    【讨论】:

    • 问题是它给我所有的 ping(每 10 秒)它不是我想要的。您的输出是CalculatedTime |平计数 2017-11-07-12:20:03 | 1 2017-11-07-12:20:13 | 1 这就是我现在想要的
    【解决方案2】:

    尝试使用转换和连接小时数的方法。 这将为您提供每小时和日期时间格式的 ping 计数,与您在 SQL Server 2012 中使用 FORMAT 方法获得的相同:

    SELECT REPLACE(CONVERT(CHAR(10), date_field, 120),' ','-') + '-' + RIGHT('0' + CONVERT(VARCHAR(2), DATEPART(HOUR, date_field)), 2) + ':00:00' as CalculatedTime,
    COUNT(PingLogID) AS PingCount
    FROM tbl_PingLog
    GROUP BY REPLACE(CONVERT(CHAR(10), date_field, 120),' ','-') + '-' + RIGHT('0' + CONVERT(VARCHAR(2), DATEPART(HOUR, date_field)), 2) + ':00:00'
    ORDER BY REPLACE(CONVERT(CHAR(10), date_field, 120),' ','-') + '-' + RIGHT('0' + CONVERT(VARCHAR(2), DATEPART(HOUR, date_field)), 2) + ':00:00'
    

    【讨论】:

    • 虽然这只是来自@gotqn 的修改版回答:P
    • 是的,它运行良好,但我不想过时日期/日期时间格式。我可以在 c# 端使用字符串格式来做到这一点。这不是我真正想要的。但它的作品谢谢。
    • @BMErEr 如果有人回答您的问题,请始终标记已回答或投票。
    • 我想升,但因为我的名声我不能,但我不能给分数,因为这不是我真正想要的
    • 如果您使用的是 SQL Server 2008,恐怕这就是您所得到的全部了。
    【解决方案3】:

    其他解决方案的简化版

    SELECT 
        replace(convert(varchar(13),PingLogDate,120),' ','-')+':00:00'  AS CalculatedTime, 
        COUNT(PingLogID) AS PingCount
    FROM
        tbl_PingLog
    GROUP BY 
        convert(varchar(13),PingLogDate,120)
    ORDER BY CalculatedTime
    

    【讨论】:

    • 正如我告诉 Nitin_g3 “我不想放弃日期/日期时间格式。我可以在 c# 端使用字符串格式来做到这一点。这不是我真正想要的。”
    • docs.microsoft.com/en-us/sql/t-sql/functions/…Format 的返回类型是 nvarcharnull。即使您的第一个解决方案也不会返回日期时间。并且 yyyy-MM-dd-HH:00:00 不是有效的日期时间格式。如果您希望它是日期时间,则应将其转换回日期时间。像 cast(convert(varchar(13),b_datetime,120)+':00:00' as datetime)
    【解决方案4】:

    在你的代码中使用这个简单的语句怎么样?

    declare @date datetime = getdate()
    select DATEADD(dd, DATEDIFF(dd, 0, @date), 0)
    

    结果类似于2017-11-25 00:00:00.000

    这是从datetime 字段中修剪时间的最佳方法

    【讨论】:

    • 我不想从日期时间修剪时间。但如果我想这样做,我会喜欢那个演员表(mydate as date)
    猜你喜欢
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多