29

次のテーブルがあるとします。

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     

スター付きの行、つまりValue変更された行を選択するにはどうすればよいですか? 基本的に、変更された時間を見つけようとしているValueので、それらの時間間隔に基づいて他のクエリを実行できます。Value解決策は、知っていることやTime事前に依存するべきではありません。

これはそれほど難しいことではないように思えます (しかし、私にとっては十分難しいようです!)。

現在、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- analytic-function/しかし、私のクエリは 1 時間経っても完了しませんでした! 結合により、行サイズが管理不能なものに爆発すると思います(または、私はそれを台無しにしました)。

この問題は C# コードと複数の db 呼び出しで解決できますが、テーブル値関数または SP で実行できる方がはるかに優れているようです。

また、増加でのみ機能するソリューションValueは、それが簡単であれば問題ありません。

4

3 に答える 3

33

これがあなたが求めているものだと思います:

;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;

結果セットが大きく、サポートする適切なインデックスがない場合、これは遅くなる可能性があります...

編集

ああ、ちょっと待ってください。値は上がるだけでなく上下します...その場合は、このはるかに遅いアプローチを試すことができます。

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;

結果:

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
于 2012-06-20T20:18:33.417 に答える