2009-04-09 11 views
9

Per seguenti dati:La selezione di tutte le righe fino a quando prima occorrenza del dato valore

data | valore | controllare
2009 | 5 | 1
2008 | 5 | 1
2007 | 5 | 1
2006 | 5 | 0
2005 | 5 | 0
2004 | 5 | 1
2003 | 5 | 1
2002 | 5 | 1

ho bisogno di selezionare tutte le righe a partire dal 2009 indietro fino a prima occorrenza di 0 nella colonna di controllo:

data | valore | controllare
2009 | 5 | 1
2008 | 5 | 1
2007 | 5 | 1

Ho provato con la funzione di ritardo, ma sono stato in grado di controllare solo un mese indietro.

Sto lavorando su Oracle 10g.

Grazie in anticipo,

UPDATE:

Tutto sembra funzionare bene, il mio set di dati di test è troppo piccolo per dire qualcosa circa le differenze di prestazioni. Grazie per tutti i tuoi input!

risposta

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 

o meglio:

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 

Quest'ultimo query realmente fermare la scansione non appena incontra il primo zero sotto controllo.

+0

Questo sarebbe solo "stop scansione" se l'ordine interiore è stata soddisfatta da un indice, nel qual caso si potrebbe anche utilizzare la prima versione. In caso contrario, Oracle ordinerà per intero il set di risultati interno. –

+0

Certo che lo farà. Ma questa soluzione richiede un solo indice su (data) per funzionare in modo efficiente, mentre la soluzione MAX() richiede anche un indice su (controllo, data). – 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

Non sono sicuro che "DECLARE @mytable TABLE" funzionerà in Oracle :) – Quassnoi

+0

lol. vecchie abitudini ... –

Problemi correlati