1

SQLで次の射影を行う方法はありますか? 順序に基づいて 2 番目の列が変化しない行を削除しますか?

FROM          TO
1   504     1   504
2   508     2   508
3   504     3   504
4   504     7   508
5   504     8   504
6   504     9   508
7   508     10  504
8   504     15  508
9   508     16  504
10  504         
11  504         
12  504         
13  504         
14  504         
15  508         
16  504         
17  504         
18  504         
19  504
4

2 に答える 2

2

使用している RDBMS によっては、LAG および LEAD 分析関数を使用して前/次の行を調べることができます。

SELECT
  a.* 
FROM (
  SELECT
    id
  , value
  , LAG(value) OVER (ORDER BY id) previous_value
  FROM some_table
) a
WHERE a.previous_value IS NULL OR a.value != a.previous_value

ここで、インライン ビューは、前の行の値を持つ列を含むデータを引き出します (id 順の場合)。外側のクエリの WHERE 句は、値が前の値と同じである行を除外します (そして、明らかに NULL の previous_value を持つ最初の行を含めるようにします)。

于 2013-01-03T15:07:55.390 に答える
1

標準 SQL でこれを行うには、相関サブクエリを使用できます。アイデアは、以前の値を取得し、現在の値を持つ行のみを保持することです:

select a.*
from (select t.*
             (select max(id) from t t2 where t2.id < t.id) as pevid
      from t
     ) a left outer join
     t aprev
     on a.previd = aprev.id
where aprev.value <> a.value or aprev.value is null

これは実際にはlag()関数の実装ですが、ウィンドウ関数はありません。

これは、top/limit/rownum を使用してサブクエリで order by を実行することもできます。

select a.*
from (select t.*
             (select top 1 id from t t2 where t2.id < t.id order by id desc) as pevid
      from t
     ) a left outer join
     t aprev
     on a.previd = aprev.id
where aprev.value <> a.value or aprev.value is null

次に、これを単純化して、最後の結合を削除できます。

select a.*
from (select t.*
             (select top 1 val from t t2 where t2.id < t.id order by id desc) as pevval
      from t
     )
where a.prevval <> a.value or a.prevval is null
于 2013-01-03T15:14:55.807 に答える