我是TSQL的新手。 我有一张桌子,里面有一辆名为ODOMETER的车辆。我必须在从1月1日到结束的一段时间内得到公里数。 SELECT MAX(里程表) - MIN(里程表)为TotalKm FROM Table 这将在理想的测试场景中起作用,但Odomometer可以在任何时间重置为0。 有人可以帮忙解决我的问题,谢谢。
我正在使用MS SQL 2012
记录示例:
Date Odometer value
datetime var, 37210
datetime var, 37340
datetime var, 0
datetime var, 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
答案 1 :(得分:0)
我认为使用LAG的Karl解决方案比我的好,但无论如何:
;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]