2016-08-23 30 views
3

我有一个列值和时间戳的表。这些值每秒都在进来。所以,我有数据如下在SQL中如何不选择列值与其上一行中的行相同的行

V1 T1 
V1 T2 
V2 T3 
V3 T4.. 

等。所以时间戳将保持增长,但值可以是相同的,他们不会改变。 我想只选择其中值不同于上一行的行。 所以我想减少数据并只选择数据发生变化的记录。 有人会知道如何做到这一点?

+0

我删除了'mysql'标签。使用正在使用的数据库更正标签。 –

+0

@vkp你是怎么知道要删除哪一个的? – Strawberry

+0

窗口功能,LEAD和LAG。 – DVT

回答

2

这仅适用于SQL Server 2012或更高版本

WITH cte AS (
    SELECT 
     V,T, 
     LAG(V) OVER (ORDER BY T) AS LAST_V 
    FROM 
     TABLE 
    ) 
SELECT 
    V, T 
FROM 
    cte 
WHERE 
    V <> LAST_V OR LAST_V IS NULL; 

的LAST_V为V的前行中的值,由T.下令所以如果V <> LAST_V这意味着V是不一样的LAST_V这是问了什么。 LAST_V为NULL的情况意味着您位于第一行。

+0

'WHERE'不需要'LAST_V <> 0',这意味着ORDER BY隐含的行之间的V没有变化吗?看起来V <> LAST_V只是包括*值*与* delta *不同的地方 - 也许我只是没有看清楚它? –

+0

@DavidW我很困惑。我的意思是:LAST_V是前一行中V的值,按T排序。所以如果V <> LAST_V,这意味着V与LAST_V不一样,这就是所要求的。 LAST_V为NULL的情况意味着您位于第一行。我错过了什么吗? – DVT

+0

@vkp谢谢。我刚刚(这实际上只是我上面的评论)。 – DVT

1
Declare @YourTable table (Col1 varchar(25),Col2 varchar(25)) 
Insert Into @YourTable values 
('V1','T1'), 
('V1','T2'), 
('V2','T3'), 
('V3','T4') 

;with cteBase as (
    Select *,RowNr=Row_Number() over(Partition By Col1 Order By Col2 Desc) From @YourTable 
) 
Select * from cteBase where RowNr=1 

返回

Col1 Col2 RowNr 
V1  T2  1 
V2  T3  1 
V3  T4  1 

或者你可以用与领带条款

Select Top 1 With Ties * 
    From @YourTable 
    Order By Row_Number() over(Partition By Col1 Order By Col2 Desc) 

返回

Col1 Col2 
V1  T2 
V2  T3 
V3  T4  
+0

我不认为分区会在这里工作。您只需根据当前行的值检查上一行或下一行的值。 –

+0

@vkp你很可能是正确的。我可能误解了要求 –

相关问题