2009-04-09 41 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 | 1

我需要從2009年的所有行回來,直到檢查柱0第一次出現:

日期|價值|檢查
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將對內部結果集進行全面排序。 – 2009-04-12 11:19:48

+0

當然會。但是這個解決方案只需要一個(日期)索引來有效地工作,而MAX()解決方案也需要一個(check,date)索引。 – Quassnoi 2009-04-12 18:54:33

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) 
相關問題