Alternate of lead lag function in SQL Server 2008

时光总嘲笑我的痴心妄想 提交于 2019-12-17 16:34:31

问题


I want to compare the current row with a value in the next row. SQL has LEAD and LAG functions to get the next and previous values but I can not use them because I am using SQL Server 2008.

So how do I get this?

I have table with output

+----+-------+-----------+-------------------------+
| Id | ActId |  StatusId |       MinStartTime      |
+----+-------+-----------+-------------------------+
| 1  |  42   | 1         | 2014-02-14 11:17:21.203 |
| 2  |  42   | 1         | 2014-02-14 11:50:19.367 |
| 3  |  42   | 1         | 2014-02-14 11:50:19.380 |
| 4  |  42   | 6         | 2014-02-17 05:25:57.280 |
| 5  |  42   | 6         | 2014-02-19 06:09:33.150 |
| 6  |  42   | 1         | 2014-02-19 06:11:24.393 |
| 7  |  42   | 6         | 2014-02-19 06:11:24.410 |
| 8  |  42   | 8         | 2014-02-19 06:44:47.070 |
+----+-------+-----------+-------------------------+

What I want to do is if the current row status is 1 and the next row status is 6 and both times are the same (up to minutes) then I want to get the row where the status is 1.

Eg: Id 6 row has status 1 and Id 7 row has status 6 but both times are the same ie. 2014-02-19 06:11

So I want to get this row or id for status 1 ie. id 6


回答1:


In your case, the ids appear to be numeric, you can just do a self-join:

select t.*
from table t join
     table tnext
     on t.id = tnext.id - 1 and
        t.StatusId = 1 and
        tnext.StatusId = 6 and
        datediff(second, t.MinStartTime, tnext.MinStartTime) < 60;

This isn't quite the same minute. It is within 60 seconds. Do you actually need the same calendar time minute? If so, you can do:

select t.*
from table t join
     table tnext
     on t.id = tnext.id - 1 and
        t.StatusId = 1 and
        tnext.StatusId = 6 and
        datediff(second, t.MinStartTime, tnext.MinStartTime) < 60 and
        datepart(minute, t.MinStartTime) = datepart(minute, tnext.MinStartTime);



回答2:


Just posting a more complex join using two different tables created with Gordon's foundation. Excuse the specific object names, but you'll get the gist. Gets the percentage change in samples from one to the next.

SELECT 
      fm0.SAMPLE curFMSample
    , fm1.SAMPLE nextFMSample
    , fm0.TEMPERATURE curFMTemp
    , fm1.TEMPERATURE nextFMTemp
    , ABS(CAST((fm0.Temperature - fm1.Temperature) AS DECIMAL(4, 0)) / CAST(fm0.TEMPERATURE AS DECIMAL(4, 0))) AS fmTempChange
    , fm0.GAUGE curFMGauge
    , fm1.GAUGE nextFMGauge
    , ABS(CAST((fm0.GAUGE - fm1.GAUGE) AS DECIMAL(4, 4)) / CAST(fm0.GAUGE AS DECIMAL(4, 4))) AS fmGaugeChange
    , fm0.WIDTH curFMWidth
    , fm1.WIDTH nextFMWidth
    , ABS(CAST((fm0.Width - fm1.Width) AS DECIMAL(4, 2)) / CAST(fm0.Width AS DECIMAL(4, 2))) AS fmWidthChange
    , cl0.TEMPERATURE curClrTemp
    , cl1.TEMPERATURE nextClrTemp
    , ABS(CAST((cl0.Temperature - cl1.Temperature) AS DECIMAL(4, 0)) / CAST(cl0.TEMPERATURE AS DECIMAL(4, 0))) AS clrTempChange
FROM 
    dbo.COIL_FINISHING_MILL_EXIT_STR02 fm0
    INNER JOIN dbo.COIL_FINISHING_MILL_EXIT_STR02 fm1 ON (fm0.SAMPLE = fm1.SAMPLE - 1 AND fm1.coil = fm0.coil)
    INNER JOIN dbo.COIL_COILER_STR02 cl0 ON fm0.coil = cl0.coil AND fm0.SAMPLE = cl0.SAMPLE
    INNER JOIN dbo.COIL_COILER_STR02 cl1 ON (cl0.SAMPLE = cl1.SAMPLE - 1 AND cl1.coil = cl0.coil)
WHERE
    fm0.coil = 2015515872



回答3:


Well, I would suggest a very simple solution if you do not have a sequential row id but a different step (if some records were deleted for example..):

declare @t table(id int, obj_name varchar(5))

insert @t select 1,'a'

insert @t select 5,'b'

insert @t select 22,'c'

insert @t select 543,'d'

---------------------------------
select *from @t

Example Source Table @t:

---------------------------------
id  obj_name

1   a

5   b

22  c

543 d

---------------------------------

Select with self join

select obj_name_prev=tt.obj_name, obj_name_next=min(t.obj_name)

from @t t

join @t tt on tt.id < t.id

group by tt.obj_name

Result:

---------------------------------
obj_name_prev   obj_name_next

a   b

b   c

c   d

---------------------------------


来源:https://stackoverflow.com/questions/22188514/alternate-of-lead-lag-function-in-sql-server-2008

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