2017-07-11 19 views
0

私はこのようなテーブルを持っています。Oracle:小さな値と最初の大きな値を取得

ID  Name  Value 
1  Sample1  10 
2  Sample2  20 
3  Sample3  30 
4  Sample4  40 

そして、より小さな値を含むすべての行とより大きな値を含む最初の行を取得したいと思います。

たとえば、値の列に '25'をパラメータとして送信すると、次の表が必要になります。

ID  Name  Value 
1  Sample1  10 
2  Sample2  20 
3  Sample3  30 

私はこの時点で前もって感謝しています。

+0

例では、引数として渡す値が20の場合の結果はどうなりますか?問題のステートメントでは、「より小さい」と「より大きい」と言いますが、「同等」はどうですか?次に、値25を渡すと、ID = 4の行の値は30、ID = 3になりますか?両方の行を選択しますか(全体的に4行すべてを選択します)?これは解決策ではなく要件に関する質問です。彼らはコードを書こうとする前に非常に明確な答えを持っていなければなりません。 – mathguy

+0

どのOracleのバージョンを使用していますか? Oracle 12.1以降の場合、問題はMATCH_RECOGNIZEを使用すると非常に効率的なソリューションになります。バージョンがわからない場合は、 'select * from v $ version'を実行してください。バージョンは、12.1.0.2.0のように5つの部分で構成される「番号」です。 – mathguy

+0

@mathguy返事をありがとう。まず、行に繋がりがある場合は、そのうちの1つのみが必要です。次に、パラメータとして20を送信すると、クエリは最初の2つの行のみを返す必要があります。そして第3に、私のOracleバージョンは古いものです:)実際に10g(10.2.0.4.0) –

答えて

3

レスキュー機能に救済!

create table your_table (
id  number, 
value number) 

insert into your_table 
select level, level * 10 
from dual 
connect by level <= 5 

select * from your_table 

id | value 
----+------ 
1 | 10 
2 | 20 
3 | 30 
4 | 40 
5 | 50 

ここでは、lag()を使用します。フィールド、オフセット、および既定値を指定します(前の行がない最初の行)。

select id, value, lag(value, 1, value) over (order by value) previous_value 
from your_table 

id | value | previous_value 
---+-------+--------------- 
1 | 10 | 10 
2 | 20 | 10 
3 | 30 | 20 
4 | 40 | 30 
5 | 50 | 40 

whereを適用します。

select id, value 
from (
    select id, value, lag(value, 1, value) over (order by value) previous_value 
    from your_table) 
where previous_value < 25 

私のために働きます。

id | value 
----+------ 
1 | 10 
2 | 20 
3 | 30 

もちろん、ネクタイに関するポリシーが必要です。たとえば、2つの行が同じ値を持ち、両方が最初のものである場合はどうなりますか?両方を保持したいのか、どちらか一方のみを保持したいのですか?あるいは、あなたはタイを壊すための他の基準を持っているかもしれません(idでソート)。しかし、その考えはかなり単純です。

+0

あなたより若い男! **ラグ()**機能は仕事をします!そして、もしネクタイがあれば、私は値の一つだけを必要とし、他は必要ない。 –

0

あなたはこのようなクエリ試すことができます。Oracleで

SELECT * FROM YourTableName WHERE Value < 25 OR ID IN (SELECT TOP 1 ID FROM YourTableName WHERE Value >= 25 ORDER BY Value) 
+0

この例は私の問題を解決する方法を示しました。 –

0

を、あなたはこれを試すことができます(ただし、参照の答え「若い男それ」、私はそれは私のものよりはましだと思う):

SELECT * FROM (
    SELECT ID, NAME, VALUE, 1 AS RN 
    FROM YT 
    WHERE VALUE < 25 
    UNION ALL  
    SELECT ID, NAME, VALUE, ROW_NUMBER()OVER (ORDER BY VALUE) AS RN 
    FROM YT 
    WHERE VALUE > 25 
    ) A 
    WHERE RN=1; 
+0

ありがとう、私のテーブルの別のものでこれを試してみよう) –

+0

@CemKahramanoğluとにかく、たくさんのレコードがある場合は、両方のクエリ(私とYoungManのどちらか)のパフォーマンスを見てください。両方とも動作しますが、どちらが最善かわかりません。 – etsa

関連する問題