如何在SQL Server

时间:2016-10-18 04:50:52

标签: sql sql-server-2008

我编写了一个连接多个表的查询,并寻求帮助以找到两行相同标识符之间的时差。

示例: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
  列名称无效'。

2 个答案:

答案 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

示例输出:

enter image description here

如果要显示所有行,但只需要前两行的时差,请添加一个额外的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

示例输出:

enter image description here