SQL Sever 2012
原始数据
ID VAL Time
+---+----+---------------------+
| 2 | 1 | 2015-05-09 12:54:39 |
| 3 | 10 | 2015-05-09 12:54:39 |
| 2 | 1 | 2015-05-09 12:56:39 |
| 3 | 10 | 2015-05-09 12:56:39 |
| 2 | 5 | 2015-05-09 13:48:30 |
| 3 | 16 | 2015-05-09 13:48:30 |
| 2 | 7 | 2015-05-09 15:01:09 |
| 3 | 20 | 2015-05-09 15:01:09 |
+---+----+---------------------+
我有一张表,其中VAL正在及时增加。我想操纵数据来显示每个ID随着时间的推移增加了多少VAL。所以Val在Time2 - Val at Time1
理想的结果:
ID VALI Time
+---+----+---------------------+
| 2 | 0 | 2015-05-09 12:56:39 |
| 3 | 0 | 2015-05-09 12:56:39 |
| 2 | 4 | 2015-05-09 13:48:30 |
| 3 | 6 | 2015-05-09 13:48:30 |
| 2 | 2 | 2015-05-09 15:01:09 |
| 3 | 4 | 2015-05-09 15:01:09 |
+---+----+---------------------+
到目前为止代码:
select
t1.Time,t1.[ID],t2.[VAL]-t1.[VAL] AS [ValI]
from #tempTable t1
inner join #tempTable t2 ON t1.[ID]=t2.[ID]
AND t1.[Time]<t2.[Time]
我需要计算当前时间戳与当前时间戳之前的时间之间的差异,而不是当前时间戳之前的所有时间戳。截至目前,当VAL没有改变时,我得到了很多重复值。
答案 0 :(得分:2)
你可以使用它。
DECLARE @MyTable TABLE (ID INT, VAL INT, [Time] DATETIME)
INSERT INTO @MyTable VALUES
(2, 1 ,'2015-05-09 12:54:39'),
(3, 10 ,'2015-05-09 12:54:39'),
(2, 1 ,'2015-05-09 12:56:39'),
(3, 10 ,'2015-05-09 12:56:39'),
(2, 5 ,'2015-05-09 13:48:30'),
(3, 16 ,'2015-05-09 13:48:30'),
(2, 7 ,'2015-05-09 15:01:09'),
(3, 20 ,'2015-05-09 15:01:09')
;WITH CTE AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY [Time]) RN FROM @MyTable
)
SELECT T1.ID, T2.VAL - T1.VAL AS VALI, T2.Time FROM CTE T1
INNER JOIN CTE T2 ON T1.ID = T2.ID AND T1.RN = T2.RN - 1
ORDER BY T1.[Time], T1.ID
结果:
ID VALI Time
----------- ----------- -----------------------
2 0 2015-05-09 12:56:39.000
3 0 2015-05-09 12:56:39.000
2 4 2015-05-09 13:48:30.000
3 6 2015-05-09 13:48:30.000
2 2 2015-05-09 15:01:09.000
3 4 2015-05-09 15:01:09.000
答案 1 :(得分:0)
您可以先按时间降序排序#tempTable,然后按ID分区。
然后您的加入成为:
select
t1.Time,
t1.[ID],
t1.[VAL] - t2.[VAL] AS [ValI]
from #tempTable t1
inner join #tempTable t2 ON t1.[ID] = t2.[ID]
AND t2.Rank = (t1.Rank + 1)
答案 2 :(得分:0)
这应该有效:
select id, time, val-prevval val1 from (
select * , lag(val, 1, 0) over(partition by id order by val, time) prevVal from #Temp)A
order by time
答案 3 :(得分:0)
如果您有LAG
<强> DEMO 强>
SELECT
id
, val - LAG(val, 1) OVER (PARTITION BY id ORDER BY time ASC) AS VALI
, time
FROM #TempTable
ORDER BY time ASC, ID ASC
答案 4 :(得分:0)
LAG()
在SQL 2012中可用。这使您可以获取当前行val
并从上一行中减去val
,按{{1}分组并按id
排序。对于前两行,这将返回Time
,因为他们没有先前的记录可供比较。您可以通过将查询置于子选择中然后应用NULL
来排除它们,也可以使用WHERE valDiff IS NULL
&gt;的第三个参数来默认valDiff
。 LAG()
将前两行默认为LAG(Val,1,0)
。
MS SQL Server 2017架构设置:
0
查询1 :
CREATE TABLE t1 ( ID int, VAL int, [Time] datetime) ;
INSERT INTO t1 ( ID, Val, [Time] )
VALUES
( 2, 1 , '2015-05-09 12:54:39')
, ( 3, 10, '2015-05-09 12:54:39')
, ( 2, 1 , '2015-05-09 12:56:39')
, ( 3, 10, '2015-05-09 12:56:39')
, ( 2, 5 , '2015-05-09 13:48:30')
, ( 3, 16, '2015-05-09 13:48:30')
, ( 2, 7 , '2015-05-09 15:01:09')
, ( 3, 20, '2015-05-09 15:01:09')
;
<强> Results 强>:
SELECT s1.ID
, s1.ValDiff
, FORMAT(s1.[Time], 'yyyy-MM-dd hh:mm:ss') AS fTime
FROM (
SELECT ID
, Val - LAG(Val,1) OVER ( PARTITION BY ID ORDER BY [Time],ID ) AS ValDiff
, [Time]
FROM t1
) s1
WHERE s1.valDiff IS NOT NULL
ORDER BY s1.[Time],s1.ID