我是这个网站的新手,但请耐心等待.
我正在尝试使用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