SQL Server DATEDIFF Computed Column Between Rows

折月煮酒 提交于 2020-07-09 04:43:49

问题


I currently have a table similar to this -

RecordTime                    Running     Fault
-----------------------------------------------
2016-09-15 11:32:01.00        0           202
2016-09-15 11:32:08.00        1           202
2016-09-15 11:39:31.00        0           21
2016-09-15 11:40:07.00        1           4
2016-09-15 11:42:11.00        0           21
2016-09-15 11:42:39.00        1           45

I then wanted to calculate the time difference between the RecordTimes for each record. For this I am using the following -

WITH    rows AS
        (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY RecordTime) AS rn
        FROM    dbo.Table1
        )
SELECT  DATEDIFF(second, mc.RecordTime, mp.RecordTime)
FROM    rows mc
JOIN    rows mp
ON      mc.rn = mp.rn - 1

Which returns -

(No column name)
----------------
7
443
36
124
28
303

What I actually want to do, though, is create a computed column in the original table that gives me these values. Is this possible?

I thought that I might be able to convert the query into a UDF and then reference that in the column, but I'm not very experienced with that kind of work.

---edit---

Final result should be -

RecordTime                    Running     Fault     Diff
--------------------------------------------------------
2016-09-15 11:32:01.00        0           202       7
2016-09-15 11:32:08.00        1           202       443
2016-09-15 11:39:31.00        0           21        36
2016-09-15 11:40:07.00        1           4         124
2016-09-15 11:42:11.00        0           21        28
2016-09-15 11:42:39.00        1           45        303

回答1:


I recommend you to use a view for this purpose:

CREATE VIEW Table1_vw 
AS
WITH cte AS (
    SELECT  *, 
            ROW_NUMBER() OVER (ORDER BY RecordTime) AS rn
    FROM    dbo.Table1
)
SELECT  mc.RecordTime,
        mc.Running,
        mc.Fault,
        DATEDIFF(second, mc.RecordTime, mp.RecordTime) Diff
FROM cte mc
LEFT JOIN cte mp
ON mc.rn = mp.rn - 1

Since you are using SQL Server 2012 you can use LEAD function:

CREATE VIEW Table1_vw 
AS
SELECT  RecordTime,
        Running,
        Fault,
        DATEDIFF(second,RecordTime,LEAD(RecordTime,1,NULL) OVER (ORDER BY RecordTime ASC) ) as Diff
FROM Table1
GO



回答2:


How about:

CREATE FUNCTION GetTimeDiff (@time datetime)
RETURNS INT 
AS BEGIN
    declare @t1 datetime 

    DECLARE @Ret int

    SELECT @t1 = RecordTime 
    FROM (
        SELECT  RecordTime, 
                ROW_NUMBER() OVER (ORDER BY RecordTime DESC) AS rn
        FROM Table1
        WHERE RecordTime < @time
    ) i
    WHERE i.rn = 1

    SELECT @Ret = DATEDIFF(second, @t1, @time)
    RETURN @Ret
END
GO

ALTER TABLE Table1
ADD TimeDiff AS dbo.GetTimeDiff(RecordTime) 
GO

You need to add logic to the function to handle NULL @t1 etc.

Update to make it work with the next row:

 ROW_NUMBER() OVER (ORDER BY RecordTime ASC) AS rn
        FROM Table1
        WHERE RecordTime > @time

And this to make all values positive rather than negative:

SELECT @Ret = ABS(DATEDIFF(second, @t1, @time))


来源:https://stackoverflow.com/questions/39529045/sql-server-datediff-computed-column-between-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!