2015-10-02 75 views
0

我有一個表像日期之間的值之間的差異:SQL - 使用的GUID

[日期],[GUID],[值(INT)

數據是這樣的:

10/1, id1, 10 
10/1, id2, 5 
10/2, id1, 12 
10/2, id2, 14 
10/3, id1, 11 

我要回:

10/1, id1, 2 
10/1, id2, 9 
10/2, id1, -1 

同一ID的比賽,抓住了第二天(不是下一個日期)值,使用過去值,SUBT racting。

所以10/1,ID1,2經由

10/1, id1, 10 
10/2, id1, 12 

所以我們返回的第一天,10/1接收,並且ID,ID1,和12-10 = 2

我該如何通過SQL來做到這一點?

謝謝!

+2

您正在使用哪個數據庫管理系統:

select d.*, lead(value) over (partition by id order by date) as next_value from data d; 

爲特定的輸出,你需要一個子查詢? Postgres的?甲骨文? –

+0

日期差異總是爲1或只是每個ID的下一個日期? –

+0

在SqlServer的情況下,請包括年份2008,2012,2014 –

回答

0

未經測試。 從t1連接獲取所有值到一個聯合子查詢,其唯一目的是爲每個guid找到高於該guid的日期的下一個最小日期。然後加入再次設置整個值並僅限於識別的guid和min date,使用此t3值從初始t1設置值中減去。

SELECT t1.date, t1.guid, t3.value-t1.value 
FROM tableName t1 
INNER JOIN (SELECT min(t2.Date) minDate, t2.GUID 
      FROM TableName t2 
      WHERE t2.Date> t1.date 
      GROUP BY t2.GUID) B 
on B.GUID = t1.guid 
INNER JOIN tableName t3 
on t3.GUID= T1.guid 
and t3.date = b.mindate 

這裏假設的是,guid和date是唯一對,所有記錄都不重複。

0

這裏還有一個基於你給出的內容。這可能是你正在尋找

declare @test table 
(
    dateId date, 
    gguid uniqueidentifier, 
    value int 
) 

insert into @test(dateId,gguid,value) 
Values('10/1/2015','1DFE73AF-7940-4CDC-A22F-92DA8DEF7B6E', 10), 
('10/1/2015', '6A057D92-7279-4E34-8ADC-870E45B5D49A', 5), 
('10/2/2015', '1DFE73AF-7940-4CDC-A22F-92DA8DEF7B6E', 12), 
('10/2/2015', '6A057D92-7279-4E34-8ADC-870E45B5D49A', 14), 
('10/3/2015', '1DFE73AF-7940-4CDC-A22F-92DA8DEF7B6E', 11); 

with test 
as 
(
select dateId,gguid,value 
,RANK() over (partition by gguid order by dateId) as RNK 
from @test 
) select T.dateId,T.gguid,T.value, IsNull(T.value-X.value,0) as lastday from test T left join (select dateId,gguid,value, RNK+1 as RNK from test) AS X 
on X.gguid = t.gguid and T.RNK = X.RNK 
0

你應該使用LAG()

Sql Fiddle Demo

SELECT [Date], [guid], [value], 
     LAG([value],1, null) OVER (PARTITION BY [guid] ORDER BY [Date]) as previousValue 
FROM Table1 

輸出

忽略行,其中PreviousValue IS NULL然後計算Value - PreviousValue

|  Date | guid | value | previousValue | 
|------------|------|-------|---------------| 
| 2001-10-01 | id1 | 10 |  (null) | 
| 2001-10-02 | id1 | 12 |   10 | 
| 2001-10-03 | id1 | 11 |   12 | 
| 2001-10-01 | id2 |  5 |  (null) | 
| 2001-10-02 | id2 | 14 |    5 | 

一起

SELECT [Date], [guid], [value] - previousValue as [value] 
FROM (
    SELECT [Date], [guid], [value], 
     LAG([value],1, null) OVER (PARTITION BY [guid] ORDER BY [Date]) as previousValue 
    FROM Table1 
) T 
WHERE T.previousValue IS NOT NULL 
ORDER BY [Date], [guid] 
0

包木窗在SQL Server 2012+,你會使用lead()

如果你想所有五個行,你會怎麼做:

select d.id, d.date, d.next_value 
from (select d.*, lead(value) over (partition by id order by date) as next_value 
     from data d 
    ) d 
where next_value is not null;