计算字段SQL上的上一个和下一个记录

时间:2014-10-08 06:41:58

标签: sql sql-server excel sql-server-2008 tsql

我有下表:

ID    GROUPID   oDate        oTime       Value
1     A         2014-06-01   00:00:00    100
2     A         2014-06-01   01:00:00    200
3     A         2014-06-01   02:00:00    300
4     A         2014-06-01   03:00:00    400
5     A         2014-06-01   04:00:00      0
6     A         2014-06-01   05:00:00     10
7     A         2014-06-01   06:00:00     20

我希望得到以下结果:

     A     B         C            D           E       F
----------------------------------------------------------------------
1    ID    GROUPID   oDate        oTime       Value   Result
2    1     A         2014-06-01   00:00:00    100     
3    2     A         2014-06-01   01:00:00    200     100
4    3     A         2014-06-01   02:00:00    300     100
5    4     A         2014-06-01   03:00:00    400     100
6    5     A         2014-06-01   04:00:00      0     55
7    6     A         2014-06-01   05:00:00     10     10
8    7     A         2014-06-01   06:00:00     20     10

Result公式为(以excel格式):

我将公式放在单元格F3上 - > =IF(E3=0, IF(E4=0, 0, (F2+F4)/2), (E3-E2)

如何在SQL语法中执行此操作?有谁知道如何解决这个问题? 谢谢。

4 个答案:

答案 0 :(得分:2)

你可以写成:

;with CTE as
(
select T1.ID,
       T1.GROUPID,
       T1.oDate,
       T1.oTime,
       T1.Value,      
       --T2.oTime as previousrow,
       --T3.oTime as nextrow,
       case when T1.Value = 0 then 0 --E3=0
            else T1.Value - T2.Value --(E3-E2)
       end as Result        
From test T1
left join test T2 on T1.oDate = T2.oDate and T1.GROUPID = T2.GROUPID 
                  and DATEADD(Hour, -1, T1.oTime)= T2.oTime 
left join test T3 on T1.oDate = T3.oDate and T1.GROUPID = T3.GROUPID 
                  and DATEADD(Hour, 1, T1.oTime)= T3.oTime 
)
,CTE2 as
(      select 
       T1.ID,
       T1.GROUPID,
       T1.oDate,
       T1.oTime,
       T1.Value,             
       case when T1.Value = 0 then (T2.Result + T3.Result)/2 
       --(F2+F4)/2)
       else T1.Result
       end as Result        
    From CTE T1
    left join CTE T2 on T1.oDate = T2.oDate and T1.GROUPID = T2.GROUPID 
                      and DATEADD(Hour, -1, T1.oTime)= T2.oTime 
    left join CTE T3 on T1.oDate = T3.oDate and T1.GROUPID = T3.GROUPID 
                  and DATEADD(Hour, 1, T1.oTime)= T3.oTime 
)
select ID,
       GROUPID,
       oDate,
       oTime,
       Value,             
       Result
from CTE2

DEMO

答案 1 :(得分:0)

我想我得到了你!测试这个

 SELECT DISTINCT A.*,
                CASE
                  WHEN A.VALUE = 0 THEN ( B.RESULT + C.RESULT ) / 2
                  ELSE A.RESULT
                END AS RESULT
FROM   (SELECT A.*,
               A.VALUE - B.VALUE AS RESULT
        FROM   #TEMP1 A
               JOIN #TEMP1 B
                 ON A.ID = ( B.ID + 1 )
                    AND A.GROUPID = B.GROUPID) A
       LEFT JOIN (SELECT A.*,
                         A.VALUE - B.VALUE AS RESULT
                  FROM   #TEMP1 A
                         JOIN #TEMP1 B
                           ON A.ID = ( B.ID + 1 )
                              AND A.GROUPID = B.GROUPID)B
              ON A.ID = ( B.ID + 1 )
                 AND A.GROUPID = B.GROUPID
       LEFT JOIN (SELECT A.*,
                         A.VALUE - B.VALUE AS RESULT
                  FROM   #TEMP1 A
                         JOIN #TEMP1 B
                           ON A.ID = ( B.ID + 1 )
                              AND A.GROUPID = B.GROUPID)C
              ON A.ID = ( C.ID - 1 )
                 AND A.GROUPID = C.GROUPID 

答案 2 :(得分:0)

示例

    create table YourTableName 
        (
        ID int   ,GROUPID varchar(2),   oDate date,        oTime time,       Value int
        )

        insert  YourTableName
                (ID, GROUPID, oDate, oTime, Value)
        values
                (1, 'A', '2014-06-01', '00:00:00', 100),
                (2, 'A', '2014-06-01', '01:00:00', 200),
                (3, 'A', '2014-06-01', '02:00:00', 300),
                (4, 'A', '2014-06-01', '03:00:00', 400),
                (5, 'A', '2014-06-01', '04:00:00', 0),
                (6, 'A', '2014-06-01', '05:00:00', 10),
                (7, 'A', '2014-06-01', '06:00:00', 20);

go

create view vw_yourTableName
as
with    cte_main
            as (
                select
                    ytn.ID,
                    ytn.GROUPID,
                    ytn.oDate,
                    ytn.oTime,
                    ytn.Value,
                    row_number() over (partition by ytn.GROUPID order by ytn.oDate, ytn.oTime) cte_rn
                from
                    YourTableName as ytn
                )
    select
        cte_main.ID,
        cte_main.GROUPID,
        cte_main.oDate,
        cte_main.oTime,
        cte_main.Value,
        cte_lag.Value as Result
    from
        cte_main
        left join cte_main as cte_lag
            on cte_lag.cte_rn = cte_main.cte_rn - 1

go

select * from vw_yourTableName as vytn

drop table YourTableName

<强>结果

ID  GROUPID oDate   oTime   Value   Result
1   A   2014-06-01  00:00:00.0000000    100 NULL
2   A   2014-06-01  01:00:00.0000000    200 100
3   A   2014-06-01  02:00:00.0000000    300 200
4   A   2014-06-01  03:00:00.0000000    400 300
5   A   2014-06-01  04:00:00.0000000    0   400
6   A   2014-06-01  05:00:00.0000000    10  0
7   A   2014-06-01  06:00:00.0000000    20  10

答案 3 :(得分:0)

create table #temp1 
        (
        ID int   ,GROUPID varchar(2),   oDate date,        oTime time,       Value int
        )

        insert  #temp1
                (ID, GROUPID, oDate, oTime, Value)
        values
                (1, 'A', '2014-06-01', '00:00:00', 100),
                (2, 'A', '2014-06-01', '01:00:00', 200),
                (3, 'A', '2014-06-01', '02:00:00', 300),
                (4, 'A', '2014-06-01', '03:00:00', 400),
                (5, 'A', '2014-06-01', '04:00:00', 0),
                (6, 'A', '2014-06-01', '05:00:00', 10),
                (7, 'A', '2014-06-01', '06:00:00', 20);

SELECT t.id,
       t.value,
       t.oDate,
       t.oTime,
       t.value - f.value result,
       t.groupid
INTO   #temp2
FROM   #temp1 t
       LEFT JOIN #temp1 f
              ON t.id = f.id + 1 and t.groupid = f.groupid

SELECT id,
       value,
       oDate,
       oTime,
       groupid,
       CASE
         WHEN value <> 0 THEN result
         ELSE ( (SELECT result
                 FROM   #temp2
                 WHERE  id = a.id - 1 and groupid = a.groupid)
                + (SELECT result
                   FROM   #temp2
                   WHERE  id = a.id + 1 and groupid = a.groupid) ) / 2
       END result
FROM   #temp2 a 

OR

SELECT id,
       value,
       oDate,
       oTime,
       groupid,
       CASE
         WHEN value <> 0 THEN result
         ELSE ( (SELECT result
                 FROM   (SELECT t.id,
                                t.value,
                                t.oDate,
                                t.oTime,
                                t.value - f.value result,
                                t.groupid
                         FROM   #temp1 t
                                LEFT JOIN #temp1 f
                                       ON t.id = f.id + 1
                                          AND t.groupid = f.groupid) b
                 WHERE  b.id = a.id - 1
                        AND b.groupid = a.groupid)
                + (SELECT result
                   FROM   (SELECT t.id,
                                  t.value,
                                  t.oDate,
                                  t.oTime,
                                  t.value - f.value result,
                                  t.groupid
                           FROM   #temp1 t
                                  LEFT JOIN #temp1 f
                                         ON t.id = f.id + 1
                                            AND t.groupid = f.groupid) c
                   WHERE  c.id = a.id + 1
                          AND c.groupid = a.groupid) ) / 2
       END result
FROM   (SELECT t.id,
               t.value,
               t.oDate,
               t.oTime,
               t.value - f.value result,
               t.groupid
        FROM   #temp1 t
               LEFT JOIN #temp1 f
                      ON t.id = f.id + 1
                         AND t.groupid = f.groupid) a