2017-11-22 1 views
1

次のデータセットを指定します。(MS)SQL行の選択ここでは、値が直前と直後の行の値と等しくないかどうかを確認します。

# | id ts    val 
1 | 1  1/1/2000 00:00 1 
2 | 2  1/1/2000 00:00 1 
3 | 3  1/1/2000 00:00 1 
4 | 1  1/1/2000 01:00 2 
5 | 2  1/1/2000 01:00 50 
6 | 3  1/1/2000 01:00 2 
7 | 1  1/1/2000 02:00 3 
8 | 2  1/1/2000 02:00 2 
9 | 3  1/1/2000 02:00 2 

無効なデータを特定しようとしています。このデータの性質は、累積数が常に増加するということです。

上記のデータセットの誤ったデータ行は次のとおりです。行#5

# | id ts    val 
5 | 2  1/1/2000 01:00 50 

この行の50のvalは、そのタイムスタンプの前または後のいずれかの行に等しくないので無効です。 1または2

我々はIDによってデータを並べ替える場合、これは明確で、TS

# | id ts    val 
1 | 1  1/1/2000 00:00 1 
2 | 1  1/1/2000 00:00 2 
3 | 1  1/1/2000 00:00 3 
4 | 2  1/1/2000 01:00 1 
5 | 2  1/1/2000 01:00 50 
6 | 2  1/1/2000 01:00 2 
7 | 3  1/1/2000 02:00 1 
8 | 3  1/1/2000 02:00 2 
9 | 3  1/1/2000 02:00 2 

は、誰も私がこれらの「無効」の行を選択するために、SQLのSELECT文を構築することができます。

SELECT * FROM MYTABLE 
WHERE <val is not equal to OR BETWEEN the row BEFORE or AFTER> 
ORDER BY ID, TS 

希望する結果は、行番号5を選択することです。

# | id ts    val 
5 | 2  1/1/2000 01:00 50 

ありがとうございました。私は理にかなったことを願っています。

+0

データの2つの異なる例があります。 2番目の例では、常に同じ 'id'と' ts'を持つ3つの行があります。だから、どのようにデータを注文するのですか? –

+0

行番号5はあなたの定義からうまくいきます。私は行#6の問題を参照してください。 –

答えて

0

あなたは、前後のデータに(特定の順序で)アクセスする方法を探しています。 SQL Serverでは、これはLAGLEADによって行われます。

EDITED:

SELECT * 
FROM (
    SELECT * 
     ,LAG(val, 1, 0) OVER (
      ORDER BY ts 
      ) AS PreviousData 
    ) 
    ,LEAD(val, 1, 0) OVER (
     ORDER BY ts 
     )) AS NextData) 
WHERE PreviousData =... 
AND NextData =... 
+0

ウィンドウ関数は 'SELECT'または' ORDER BY'節にしか現れません。 –

+0

@YogeshSharma、true、上記は、サブクエリの一般的な例です。正確なクエリの基準は明らかではありません。少なくとも – apomene

+0

私はLAGとLEAD(私は今読んでいます)には全く慣れていませんが、 Yohesh Sharmaのコメント –

0

結果

SELECT * FROM <table> T 
WHERE NOT EXISTS 
(
    SELECT * FROM <table> T1 
    WHERE T1.val <> T.val 
      AND T1.val BETWEEN T.val - 1 AND T.val + 1 
); 

あなたを助けるかもしれ相関サブクエリ試してみてください。

# id ts    val 
5 2 1/1/2000 01:00 50 

:上記はベースのためであるとのようなものの上にverallの質問とサンプルデータ。

+0

これは近いです。データが常に1だけインクリメントされるわけではありません。 ie:id1の場合、最初のタイムスタンプは1、2番目のタイムスタンプは30、3番目のタイムスタンプは1000の値を持つことができます。増加していますが、通常の量ではありません。単純に1、2、3、4、5、6などをカウントするのではありません。 したがって、 valから1を単に加算または減算しても、その値が間にないかどうかは判断されません。 または私はここでポイントを逃したのですか? –

+0

@AaronGloverでサンプルデータと結果を追加できます。 –

0

あなたはしたいように見える:

select t.* 
from (select t.*, lag(t.val) over (partition by t.id order by t.ts) as prev_val 
     from t 
    ) t 
where prev_val not in (val, val + 1); -- NULLs are filtered out too 

は、これはあなたが与える正確に説明はありませんが、それは全体的な質問とサンプルデータに基づいて、最も賢明なようです。

関連する問題