我是这个网站的新手,但请耐心等待。
我正在尝试使用 SQL Server 对一些数据进行GROUP BY
。
这是数据:
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
我想要实现的目标是按计算机对数据进行分组,但如果计算机的访问时间差异超过 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
因此,计算机 A
显示了两次,因为它在 09:10:00 访问过,然后在 12:25:00 再次访问过,这意味着相差超过 1 小时。
“按计算机分组”很容易,但另一方面,我不知道从哪里开始。任何有关此问题的帮助将不胜感激。
最佳答案
您无法使用简单的GROUP BY
来做到这一点。该运算符仅适用于单列 - 例如您可以按计算机名称或其他名称进行分组,但不能在分组中添加其他逻辑,例如时间差异必须大于一小时或类似的内容。
如果您使用的是 SQL Server 2005 或更高版本(您没有在问题中提及版本),您可以做的就是使用 CTE(通用表表达式)。这些提供了一种对数据进行切片和切 block 的方法。
在这里,我做了几件事 - 首先,我按 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
关于sql - 如何对时差超过一小时的记录进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10364384/