选择列值已更改的行

age*_*ega 27 sql t-sql select sql-server-2008

假设我有下表:

Value    Time
0        15/06/2012 8:03:43 PM
1        15/06/2012 8:03:43 PM     *
1        15/06/2012 8:03:48 PM 
1        15/06/2012 8:03:53 PM
1        15/06/2012 8:03:58 PM     
2        15/06/2012 8:04:03 PM     *
2        15/06/2012 8:04:08 PM
3        15/06/2012 8:04:13 PM     *
3        15/06/2012 8:04:18 PM
3        15/06/2012 8:04:23 PM
2        15/06/2012 8:04:28 PM     *
2        15/06/2012 8:04:33 PM     
Run Code Online (Sandbox Code Playgroud)

如何选择已加星标的行,Value即已更改的位置?基本上我试图找到时间Value已经改变,所以我可以根据这些时间间隔做其他查询.解决方案不应该依赖于知道ValueTime提前.

在我看来,这应该不是很难(但显然对我来说很难!).

我目前正在使用SQL Server 2008,但如果新窗口/分析功能有用,我可以访问2012.

我尝试在这里调整解决方案http://blog.sqlauthority.com/2011/11/24/sql-server-solution-to-puzzle-simulate-lead-and-lag-without-using-sql-server-2012-解析函数/但我的查询在一小时后没有完成!我认为连接将行大小爆炸到无法管理的东西(或者我搞砸了).

我可以使用C#代码和多个db调用来解决这个问题,但它似乎可以在表值函数或SP中完成,这样可以更好.

此外,Value如果更容易,只有增加的解决方案才行.

Aar*_*and 31

我想这就是你所追求的:

;WITH x AS
(
  SELECT value, time, rn = ROW_NUMBER() OVER 
  (PARTITION BY Value ORDER BY Time)
  FROM dbo.table
)
SELECT * FROM x WHERE rn = 1;
Run Code Online (Sandbox Code Playgroud)

如果结果集很大并且没有良好的支持索引,这可能会很慢......

编辑

啊,等一下,价值观上涨和下跌,而不仅仅是......如果是这种情况你可以尝试这么慢的方法:

DECLARE @x TABLE(value INT, [time] DATETIME)

INSERT @x VALUES
(0,'20120615 8:03:43 PM'),--
(1,'20120615 8:03:43 PM'),--*
(1,'20120615 8:03:48 PM'),--
(1,'20120615 8:03:53 PM'),--
(1,'20120615 8:03:58 PM'),--
(2,'20120615 8:04:03 PM'),--*
(2,'20120615 8:04:08 PM'),--
(3,'20120615 8:04:13 PM'),--*
(3,'20120615 8:04:18 PM'),--
(3,'20120615 8:04:23 PM'),--
(2,'20120615 8:04:28 PM'),--*
(2,'20120615 8:04:33 PM');

;WITH x AS
(
  SELECT *, rn = ROW_NUMBER() OVER (ORDER BY time)
  FROM @x
)
SELECT x.value, x.[time]
FROM x LEFT OUTER JOIN x AS y
ON x.rn = y.rn + 1
AND x.value <> y.value
WHERE y.value IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

结果:

value  time
-----  -----------------------
1      2012-06-15 20:03:43.000
2      2012-06-15 20:04:03.000
3      2012-06-15 20:04:13.000
2      2012-06-15 20:04:28.000
Run Code Online (Sandbox Code Playgroud)


小智 12

DECLARE @x TABLE(value INT, [time] DATETIME)

INSERT @x VALUES
(0,'20120615 8:03:43 PM'),--
(1,'20120615 8:03:43 PM'),--*
(1,'20120615 8:03:48 PM'),--
(1,'20120615 8:03:53 PM'),--
(1,'20120615 8:03:58 PM'),--
(2,'20120615 8:04:03 PM'),--*
(2,'20120615 8:04:08 PM'),--
(3,'20120615 8:04:13 PM'),--*
(3,'20120615 8:04:18 PM'),--
(3,'20120615 8:04:23 PM'),--
(2,'20120615 8:04:28 PM'),--*
(2,'20120615 8:04:33 PM');


; with temp as
(
SELECT 
    value, [time],  lag(value,1,-1) over (order by [time] ) as lastValue
FROM    @x
) 
SELECT 
    [value],[time] 
FROM 
    temp 
WHERE value <> lastValue
Run Code Online (Sandbox Code Playgroud)

结果:

value   time
---------------------------
0   2012-06-15 20:03:43.000
1   2012-06-15 20:03:43.000
2   2012-06-15 20:04:03.000
3   2012-06-15 20:04:13.000
2   2012-06-15 20:04:28.000
Run Code Online (Sandbox Code Playgroud)

  • 整洁,但值得一提的是,仅从SQL 2012开始支持. (3认同)