2017-10-18 15 views
-1

SQL查詢獲取表中發生多次的每個值的最近兩行之間的差異。 例如SQL查詢獲取表中不止一次出現的每個行項的最近兩行之間的差異

book value   date 
A 4 2017-07-17 09:16:44.480 
A 2 2017-08-15 10:05:58.273 
B 3 2017-04-15 10:05:58.273 
C 2 2017-08-15 10:05:58.273 
B 3 2017-04-13 10:05:58.273 
B 3 2017-04-12 10:05:58.273 

應該返回

A 2 
B 0 
+1

的MySQL是不一樣的SQL服務器。請僅標記您使用的數據庫。 –

+0

@RaymondNijland指出。它是SQL服務器。謝謝 –

+0

您是否只關心兩個最近行的價值差異?所以如果2017-09-10的D = 5和2017-09-12的D = 10以及2017-09-13的D = 20,那麼你是否關心2017-09-10的紀錄?在您的示例數據中,B沒有明確說明,因爲差異總是*爲零。 –

回答

0

這裏是一個解決方案:

SELECT book, MAX(value) - MIN(value) AS difference FROM (
    SELECT book, value, ROW_NUMBER() OVER (PARTITION BY book ORDER BY date DESC) AS rownum FROM t 
) AS a WHERE rownum <= 2 GROUP BY book HAVING MAX(rownum) >= 2 

這裏,它是在SQLFiddle

+1

它應該使用日期列來獲取兩個最近的記錄。這使用最小和最大記錄。 –

+0

我收到這個錯誤。 「列'值'在選擇列表中是無效的,因爲它不包含在聚合函數中 –

+0

這就是我在不測試它的情況下回答你的問題所得到的結果。編輯我的解決方案並查看http://sqlfiddle.com /#!6/06c70/2 – zambonee

0
SELECT id_pk FROM [table] GROUP BY [fields you whant to compare by] HAVING COUNT(*) > 1) 

這個select返回你的PK從元素都repited

如此,在其他列表中選擇你migth得到像

Select * from [table] where id_pk in(
SELECT id_pk FROM [table] GROUP BY [fields you whant to compare by] HAVING COUNT(*) > 1)) limit 2 

另一種選擇,這是功能性的,還沒有好,因爲我不是analising複雜性。

+0

謝謝,但我並沒有真正得到查詢的id_pk部分,我想使用日期列獲得兩個最近記錄的「值」列中的差異(減法)當然要確定最近的記錄 –

0

我會使用分析功能:

;with CTE as (
    SELECT book 
     ,value 
     ,LAG(value) OVER (PARTITION BY book ORDER BY date) last_value 
     ,ROW_NUMBER() OVER (PARTITION BY book ORDER BY date DESC) rn 
    FROM MyTable 
) 
SELECT book 
    ,value - last_value as value_change 
FROM CTE 
WHERE rn = 1 
    AND last_value IS NOT NULL 

LAG()在SQL Server 2012中添加,但即使你在一個更高的版本,您的數據庫必須具有兼容版本設置爲110或更高的他們可用。這是一個可以在SQL Server 2005或更高版本上工作的替代方案,或者數據庫兼容性90或更高版本。

;with CTE as (
    SELECT book 
     ,value 
     ,ROW_NUMBER() OVER (PARTITION BY book ORDER BY date DESC) rn 
    FROM MyTable 
) 
SELECT c1.book 
    c1.value - c2.value as value_change 
FROM CTE c1 
INNER JOIN CTE c2 
    ON c1.book = c2.book 
WHERE c1.rn = 1 
    AND c2.rn = 2 
+0

@ A.Kiva您的錯誤表明要麼從SQL Server 2012之前的版本連接到SQL Server,要麼數據庫的兼容級別是針對SQL Server 2012之前的版本。我已經添加了一個適用於SQL Server 2005和更高版本的版本。 –

+0

好的,謝謝。 –

0

計算之前添加ROWNUMBER:

create table #test ([book] char(1), [value] int, [date] datetime) 

insert into #test values ('A', 4, '2017-07-17 09:16:44.480') 
insert into #test values ('A', 2, '2017-08-15 10:05:58.273') 
insert into #test values ('B', 3, '2017-04-15 10:05:58.273') 
insert into #test values ('C', 2, '2017-08-15 10:05:58.273') 
insert into #test values ('B', 3, '2017-04-13 10:05:58.273') 
insert into #test values ('B', 3, '2017-04-12 10:05:58.273') 

;with cte as(
Select ROW_NUMBER() OVER (order by [book], [date]) as rownumber, * 
from #test) 
select distinct [1].book, abs(first_value([1].[Value]) over (partition by [1].book order by [1].rownumber desc) - [2].val2) as [Difference] 
from cte [1] 
inner join 
(select rownumber, book, first_value([Value]) over (partition by book order by rownumber desc) as val2 
from cte) [2] on [1].book = [2].book and [1].rownumber < [2].rownumber