2014-03-31 33 views
1

我是TSQL中的新成員。 我有一個名爲ODOMETER的車輛的表格。我必須從一個月的第一個月到最後一段時間內獲取km的數量。 從表 中選擇最大(里程錶) - MIN(里程錶)作爲TotalKm這將在理想的測試場景中工作,但Odomometer可以在任何時候重置爲0。 有人可以幫助解決我的問題,謝謝。TSQL - 控制數字序列

我與MS SQL 2012

的記錄實例工作:

Date   Odometer value 
datetime var, 37210 
datetime var, 37340 
datetime var, 0 
datetime var, 220 
+1

請出示相關的架構和數據的序列是有問題的,所以我們有一個更好的。 –

+1

它是哪個數據庫系統? – Szymon

+0

在您的示例數據中,如果日期分別爲3/1,3/10,3/20和3/31將覆蓋3月份,並且您希望獲得一筆用於重置的金額,對不對? Sum =(37240-37210)+(220-0)? –

回答

2

使用LAG嘗試是這樣的。還有其他方法,但這應該很容易。

編輯:更改樣本數據以包括所需的月份範圍之外的記錄。還簡化了閱讀以便於手動計算。威爾將顯示OP所簽署的第二個選項。

DECLARE @tbl TABLE (stamp DATETIME, Reading INT) 
INSERT INTO @tbl VALUES 
    ('02/28/2014',0) 
,('03/01/2014',10) 
,('03/10/2014',20) 
,('03/22/2014',0) 
,('03/30/2014',10) 
,('03/31/2014',20) 
,('04/01/2014',30) 

--Original solution with WHERE on the "outer" SELECT. 
--This give a result of 40 as it include the change of 10 between 2/28 and 3/31. 

;WITH cte AS (
    SELECT Reading 
     ,LAG(Reading,1,Reading) OVER (ORDER BY stamp ASC) LastReading 
     ,Reading - LAG(Reading,1,Reading) OVER (ORDER BY stamp ASC) ChangeSinceLastReading 
     ,CONVERT(date, stamp) stamp 
    FROM @tbl 
) 
SELECT SUM(CASE WHEN Reading = 0 THEN 0 ELSE ChangeSinceLastReading END) 
    FROM cte 
WHERE stamp BETWEEN '03/01/2014' AND '03/31/2014' 

--Second option with WHERE on the "inner" SELECT (within the CTE) 
--This give a result of 30 as it include the change of 10 between 2/28 and 3/31 is by the filtered lag. 

;WITH cte AS (
    SELECT Reading 
     ,LAG(Reading,1,Reading) OVER (ORDER BY stamp ASC) LastReading 
     ,Reading - LAG(Reading,1,Reading) OVER (ORDER BY stamp ASC) ChangeSinceLastReading 
     ,CONVERT(date, stamp) stamp 
    FROM @tbl 
    WHERE stamp BETWEEN '03/01/2014' AND '03/31/2014' 
) 
SELECT SUM(CASE WHEN Reading = 0 THEN 0 ELSE ChangeSinceLastReading END) 
    FROM cte 
+0

+1使用[LAG功能](http://technet.microsoft.com/en-us/library/hh231256.aspx) – thepirat000

+0

謝謝您的回答,卡爾,我會稍後嘗試您的解決方案。我會稍後評論並投票。 – Capanga

+0

卡爾,我已經糾正了腳本,現在它工作正常。您可以測試更改WHERE子句。非常感謝你。 – Capanga

0

我認爲卡爾的解決方案採用LAG比我的好,但不管怎麼說:

;WITH [Rows] AS 
(
    SELECT o1.[Date], o1.[Value] as CurrentValue, 
       (SELECT TOP 1 o2.[Value] 
       FROM @tbl o2 WHERE o1.[Date] < o2.[Date]) as NextValue 
    FROM @tbl o1 
) 
SELECT SUM (CASE WHEN [NextValue] IS NULL OR [NextValue] < [CurrentValue] THEN 0 ELSE [NextValue] - [CurrentValue] END) 
FROM [Rows] 
+0

謝謝你的回答,thepirat000。最好的祝福 – Capanga