我是这个网站的新手,但请耐心等待.
我正在尝试使用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 Computer”很容易,但另一方面,我不知道从哪里开始.对此问题的任何帮助将不胜感激.
解决方法
您不能使用简单的GROUP BY执行此操作.此运算符仅适用于单列 – 例如您可以按计算机名称或其他内容进行分组,但是您无法添加其他逻辑,例如时间上的差异必须大于一小时或类似的任何分组.
你可以做什么 – 只要你在sql Server 2005或更新版本(你没有在你的问题中提到版本)将使用CTE(公用表表达式).这些提供了一种切片数据的方法.
在这里,我正在做几件事 – 首先我通过ComputerName对数据进行“分区”,然后通过VisitDate进行排序,并使用ROW_NUMBER()来获取每个分区的序列号.然后第二个CTE确定每台计算机的“第一”条目 – 行号= 1 – 并且第三个最终确定每个条目的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,fc.VisitDate))
- FROM Computers c
- INNER JOIN FirstComputers fc ON c.ComputerName = fc.ComputerName
- )
- SELECT *
- FROM SelectedComputers
- WHERE RN = 1 OR DiffToFirst >= 60