tags:

views:

248

answers:

3

Hi,

For following data:

date|value|check
2009 | 5 | 1
2008 | 5 | 1
2007 | 5 | 1
2006 | 5 | 0
2005 | 5 | 0
2004 | 5 | 1
2003 | 5 | 1
2002 | 5 | 1

I need to select all rows from 2009 back until first occurrence of 0 in check column:

date|value|check
2009 | 5 | 1
2008 | 5 | 1
2007 | 5 | 1

I tried with the lag function, but I was only able to check a month back.

I am working on Oracle 10g.

Thank you in advance,

UPDATE:

All seems to work well, my test data set is too small to say anything about the performance differences. Thank you for all your inputs!

+2  A: 
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

or even better:

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

The latter query will actually stop scanning as soon as it encounters the first zero in check.

Quassnoi
This would only "stop scanning" if the inner ORDER BY was satisfied by an index, in which case you might as well use the first version. Otherwise, Oracle will sort the inner result set in full.
WW
Sure it will. But this solution needs only one index on (date) to work efficiently, while the MAX() solution also needs an index on (check, date).
Quassnoi
+1  A: 
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)
Lieven
Not sure that 'DECLARE @mytable TABLE' will work in Oracle :)
Quassnoi
lol. old habits...
Lieven
+7  A: 
SELECT * FROM mytable where date > (
   SELECT max(date) FROM mytable where check = 0    
)
kenj0418