我编写了一个连接多个表的查询,并寻求帮助以找到两行相同标识符之间的时差。
示例:Row num
是我添加的附加列,用于解释更好的
Row num NodeID Caption VolumeID Caption DateTime
1. 2245 SERVERNAME 6545 D:\RAID 10/10/16 10:25 PM
2. 2245 SERVERNAME 6545 D:\RAID 10/10/16 10:10 PM
3. 2245 SERVERNAME 6545 D:\RAID 10/10/16 9:55 PM
4. 2245 SERVERNAME 6545 D:\RAID 10/10/16 9:40 PM
5. 2245 SERVERNAME 6545 D:\RAID 10/10/16 9:25 PM
6. 2245 SERVERNAME 6545 D:\RAID 10/10/16 9:25 PM
7. 2245 SERVERNAME 7710 D:\AFS\G 10/10/16 10:25 PM
8. 2245 SERVERNAME 7710 D:\AFS\G 10/10/16 10:10 PM
9. 2245 SERVERNAME 7710 D:\AFS\G 10/10/16 9:55 PM
10. 2245 SERVERNAME 7710 D:\AFS\G 10/10/16 9:40 PM
11. 2245 SERVERNAME 7710 D:\AFS\G 10/10/16 9:25 PM
12. 2245 SERVERNAME 7711 D:\AFS\G 10/10/16 10:25 PM
13. 2245 SERVERNAME 7711 D:\AFS\G 10/10/16 10:10 PM
14. 2245 SERVERNAME 7711 D:\AFS\G 10/10/16 9:55 PM
15. 2245 SERVERNAME 7711 D:\AFS\G 10/10/16 9:40 PM
16. 2245 SERVERNAME 7711 D:\AFS\G 10/10/16 9:25 PM
17. 2245 SERVERNAME 7712 D:\AFS\C 10/10/16 10:25 PM
18. 2245 SERVERNAME 7712 D:\AFS\C 10/10/16 10:10 PM
19. 2245 SERVERNAME 7712 D:\AFS\C 10/10/16 9:55 PM
20. 2245 SERVERNAME 7712 D:\AFS\C 10/10/16 9:40 PM
21. 2245 SERVERNAME 7712 D:\AFS\C 10/10/16 9:25 PM
22. 2245 SERVERNAME 7713 D:\AFS\C 10/10/16 10:25 PM
23. 2245 SERVERNAME 7713 D:\AFS\C 10/10/16 10:10 PM
24. 2245 SERVERNAME 7713 D:\AFS\C 10/10/16 9:55 PM
25. 2245 SERVERNAME 7713 D:\AFS\C 10/10/16 9:25 PM
26. 2245 SERVERNAME 7713 D:\AFS\C 10/10/16 9:40 PM
在上面的数据示例中,标识符是Nodeid和volumeid。
每当标识符匹配时,与具有最新时间戳的记录相比,应该比较之前的记录,以确定差异。
在上面的示例中,查询应该只能匹配nodeid 2245和volumeid 6545的第1行和第2行,输出应该是15分钟
同样,对于nodeid 2245和volumeid 7710,应使用第7行和第8行进行计算。
我该怎么做?我尝试使用CTE表达但无法做到。我也尝试过子查询但失败了。
有人可以帮我写这个问题。
查询我尝试过:
WITH rows AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY [Operations-Orion].[dbo].[VolumeUsage].Datetime) AS rn
FROM [Operations-Orion].[dbo].[VolumeUsage]
)
SELECT DATEDIFF(second, mc.DateTime, mp.Datetime)
FROM [Operations-Orion].[dbo].[VolumeUsage] mc
JOIN [Operations-Orion].[dbo].[VolumeUsage] mp
ON mc.rn = mp.rn
这会引发错误:
Msg 207,Level 16,State 1,Line 10
列名称无效' Msg 207,Level 16,State 1,Line 10
列名称无效'。
答案 0 :(得分:0)
您必须在查询中使用cte而不是主表:
WITH CTEViewName AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY [Operations-Orion].[dbo].[VolumeUsage].Datetime) AS rn
FROM [Operations-Orion].[dbo].[VolumeUsage]
)
SELECT DATEDIFF(second, mc.DateTime, mp.Datetime)
FROM CTEViewName mc
JOIN CTEViewName mp
ON mc.rn = mp.rn + 1
答案 1 :(得分:0)
使用以下脚本。
;WITH cte_1
as
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY NodeID,VolumeID ORDER BY [Datetime] desc) AS rn
FROM #t
)
SELECT A.NodeID,A.Caption,A.VolumeID,A.Caption1,A.[DateTime]
,CASE DATEDIFF(HOUR, B.[DateTime], A.[DateTime])
WHEN 0 THEN CAST(DATEDIFF(MINUTE, B.[DateTime], A.[DateTime]) AS VARCHAR(10))
ELSE CAST(60 - DATEPART(MINUTE, B.[DateTime]) AS VARCHAR(10)) +
REPLICATE(',60', DATEDIFF(HOUR, B.[DateTime], A.[DateTime]) - 1) +
+ ',' + CAST(DATEPART(MINUTE, A.[DateTime]) AS VARCHAR(10))
END TimeDifference
FROM cte_1 A
join cte_1 B
on A.rn=b.rn-1
AND A.NodeID=B.NodeID AND A.VolumeID=B.VolumeID
WHERE B.rn=2 --if you dont want to limit ,comment this line
示例输出:
如果要显示所有行,但只需要前两行的时差,请添加一个额外的case语句,如下面的脚本。
;WITH cte_1
as
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY NodeID,VolumeID ORDER BY [Datetime] desc) AS rn
FROM #t
)
SELECT A.NodeID,A.Caption,A.VolumeID,A.Caption1,A.[DateTime]
,CASE WHEN b.rn=2 THEN CASE DATEDIFF(HOUR, B.[DateTime], A.[DateTime])
WHEN 0 THEN CAST(DATEDIFF(MINUTE, B.[DateTime], A.[DateTime]) AS VARCHAR(10))
ELSE CAST(60 - DATEPART(MINUTE, B.[DateTime]) AS VARCHAR(10)) +
REPLICATE(',60', DATEDIFF(HOUR, B.[DateTime], A.[DateTime]) - 1) +
+ ',' + CAST(DATEPART(MINUTE, A.[DateTime]) AS VARCHAR(10))
END ELSE NULL END TimeDifference
FROM cte_1 A
join cte_1 B
on A.rn=b.rn-1
AND A.NodeID=B.NodeID AND A.VolumeID=B.VolumeID
示例输出: