2009-04-09 7 views
9

の最初の出現まで、すべての行を選択する:|値は|次のデータについて、与えられた値

日チェック
2009 | 5 | 1
2008 | 5 | 1
2007 | 5 | 1
2006 | 5 | 0
2005年| 5 | 0
2004 | 5 | 1
2003 | 5 | 1
2002 | 5 |私は、チェック欄の0が最初に出現するまでのバック2009からすべての行を選択する必要が1


2009をチェック| |値を

日| 5 | 1
2008 | 5 | 1
2007 | 5 | 1

私はラグ機能を試しましたが、月に戻って確認することができました。

私はOracle 10gを使用しています。

は、事前に

UPDATEありがとう:

すべては私のテストデータセットは、パフォーマンスの違いについて何を言っても小さくて、うまく動作しているようです。あなたのすべての入力をありがとう!

答えて

12
SELECT * FROM mytable where date > (
    SELECT max(date) FROM mytable where check = 0  
) 
3
SELECT * 
FROM (
     SELECT m.*, 
       MIN(CASE WHEN check = 0 THEN 0 ELSE 1 END) OVER (ORDER BY date DESC)) AS mn 
     FROM mytable 
     ) 
WHERE mn = 1 

またはより良い:

SELECT * 
FROM (
     SELECT m.*, ROW_NUMBER() OVER (ORDER BY mydate DESC) AS rn 
     FROM mytable m 
     ORDER BY 
       mydate DESC 
     ) 
WHERE rownum = DECODE(check, 0, NULL, rn) 
ORDER BY 
     mydate DESC 

後者のクエリは、実際とすぐに、チェックの最初のゼロに遭遇するとスキャンを停止します。

+0

これが唯一の内側のORDER BYがあなたにも最初のバージョンを使用することがあり、その場合には、インデックス、によって満たされた場合は、「スキャンを停止」でしょう。それ以外の場合、Oracleは内部結果セットを完全にソートします。 –

+0

そうでしょう。しかし、このソリューションでは、効率的に作業するためには(日付)に1つのインデックスだけが必要ですが、MAX()ソリューションでは(チェック、日付)にインデックスが必要です。 – Quassnoi

1
DECLARE @mytable TABLE (date integer, [value] integer, [check] integer) 

INSERT INTO @mytable VALUES (2009, 5, 1) 
INSERT INTO @mytable VALUES (2008, 5, 1) 
INSERT INTO @mytable VALUES (2007, 5, 1) 
INSERT INTO @mytable VALUES (2006, 5, 0) 
INSERT INTO @mytable VALUES (2005, 5, 0) 
INSERT INTO @mytable VALUES (2004, 5, 1) 
INSERT INTO @mytable VALUES (2003, 5, 1) 
INSERT INTO @mytable VALUES (2002, 5, 1) 

SELECT * 
FROM @mytable 
WHERE date > (SELECT MAX(date) FROM @mytable WHERE [Check] = 0) 
+0

「DECLARE @mytable TABLE」がOracleで動作するかどうかわからない:) – Quassnoi

+0

lol。古い習慣... –

関連する問題