如何对时差超过一小时的记录进行分组?

Jef*_*son 9 sql sql-server group-by

我是这个网站的新手,但请耐心等待.

我正在尝试GROUP BY使用SQL Server的一些数据.

这是数据:

Computer    VisitDate
ComputerA   2012-04-28 09:00:00
ComputerA   2012-04-28 09:05:00
ComputerA   2012-04-28 09:10:00
ComputerB   2012-04-28 09:30:00
ComputerB   2012-04-28 09:32:00
ComputerB   2012-04-28 09:44:00
ComputerB   2012-04-28 09:56:00
ComputerB   2012-04-28 10:25:00
ComputerA   2012-04-28 12:25:00
ComputerC   2012-04-28 12:30:00
ComputerC   2012-04-28 12:35:00
ComputerC   2012-04-28 12:45:00
ComputerC   2012-04-28 12:55:00
Run Code Online (Sandbox Code Playgroud)

我想要实现的是通过计算机对数据进行分组,但如果计算机的访问时间超过1小时,则还要分组.这是我正在尝试做的结果:

Computer     VisitDate
ComputerA    2012-04-28 09:00:00
ComputerB    2012-04-28 09:30:00
ComputerA    2012-04-28 12:25:00
ComputerC    2012-04-28 12:30:00
Run Code Online (Sandbox Code Playgroud)

所以Computer A显示两次,因为它在09:10:00访问,然后在12:25:00再次访问,这意味着相差超过1小时.

"GROUP BY Computer"很容易,但另一方面,我不知道从哪里开始.对此问题的任何帮助将不胜感激.

mar*_*c_s 5

你不能用简单的GROUP BY. 该运算符仅适用于单列 - 例如,您可以按计算机名称或其他内容进行分组,但您不能向分组添加其他逻辑,例如时间差必须大于一小时或类似的内容。

你可以做的 - 假设你使用的是 SQL Server 2005或更高版本(你没有在问题中提到版本),那就是使用 CTE(通用表表达式)。这些提供了一种对数据进行切片和切块的方法。

在这里,我做了几件事 - 首先,我对数据进行“分区”ComputerName和排序,VisitDate并使用它ROW_NUMBER()来获取每个分区的序列号。然后,第二个 CTE 确定每台计算机的“第一个”条目 - 行号 = 1 的条目 - 第三个 CTE 最终确定VisitDate每个条目与行号 = 1 的条目相比的差异。根据第三个 CTE,我最终选择行号 = 1 的条目(每个“分区”的第一个条目),或者任何分钟数相差 60 或更多的条目。

这是代码:

;WITH Computers AS
(
    SELECT
        ComputerName, VisitDate,
        RN = ROW_NUMBER() OVER(PARTITION BY ComputerName ORDER BY VisitDate)
    FROM    
        dbo.YourComputerTable
),
FirstComputers AS
(
    SELECT ComputerName, VisitDate
    FROM Computers
    WHERE RN = 1
),
SelectedComputers AS
(
    SELECT 
        c.ComputerName, c.VisitDate, c.RN,
        DiffToFirst = ABS(DATEDIFF(MINUTE, c.VisitDate, fc.VisitDate))
    FROM Computers c
    INNER JOIN FirstComputers fc ON c.ComputerName = fc.ComputerName
)
SELECT * 
FROM SelectedComputers
WHERE RN = 1 OR DiffToFirst >= 60
Run Code Online (Sandbox Code Playgroud)