2014-10-08 54 views
0

我有如下表:
一個和下一個在計算領域的SQL記錄

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語法中執行此操作?有誰知道如何解決這個問題?
謝謝。

+0

找ROW_NUMBER()和OVER()函數從事務SQL – 2014-10-08 06:51:21

+0

喜@GrzegorzGajos,謝謝。我知道我需要使用row_number和over(也許)。但問題是,'結果'字段是計算列。讓我說我把這個列在sql視圖中。 – Haminteu 2014-10-08 06:59:44

+1

你試過'LAG'/'LEAD'嗎? – Recursive 2014-10-08 06:59:56

回答

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

+0

嗨,嘗試添加一個新行 - > GROUPID ='A',oDate ='2014-05-31'oTime = '23:00:00'oValue = '50'之前2014-06-01 00 :00:00。對於GroupID ='A',2014-06-01 00:00:00的結果應爲50. – Haminteu 2014-10-08 08:05:00

+0

嗨,我會將您的答案標記爲「答案」。只需要潤飾一點點。它應該捕獲以前的記錄,如果沒有,則爲空。 – Haminteu 2014-10-08 08:51:23

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 
+0

謝謝,但我使用的SQL 2008. – Haminteu 2014-10-08 07:05:06

+0

試試我的新答案 – Recursive 2014-10-08 07:22:54

+0

嗨,別忘了groupid,結果會計算每個groupid – Haminteu 2014-10-08 07:45:19

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 
+0

這與我的結果不同。歡呼, – Haminteu 2014-10-09 01:24:46

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 
+0

嘗試添加新記錄,groupid A,o日期2014-05-31,時間23:00:00值50 .. 2014-06-01 00:00:00 – Haminteu 2014-10-09 01:24:25

+0

@Haminteu - 應該是什麼成爲新行的ID。如果新記錄groupid A的ID爲1,則日期2014-05-31,時間23:00:00值50,現有的第一行ID變爲2意味着您不會得到空值。 – 2014-10-09 04:39:53

+0

桌上的ID實際上只是身份證號碼,當我選擇這些記錄時,我會排除ID。所以它由GroupID然後oDate排序 – Haminteu 2014-10-09 04:47:50

相關問題