2017-04-01 5 views
2

Ich mag die minimale fehlende Zahl einer Spalte mit dem Namen finden (S_NO) und der Tabelle mit dem Namen (test_table) in Oracle und ich schreibe den folgenden Code ..Mindest fehlende Zahl in Oracle finden

select 
    min_s_no-1+level missing_number 
from (
    select min(s_no) min_s_no, max(s_no) max_s_no 
    from test_table 
) connect by level <= max_s_no-min_s_no+1 
minus 
select s_no from test_table 
; 

es gibt mir die ganze fehlende Zahl als Ergebnis. Aber ich möchte die minimale Nummer auswählen. Kann mir bitte jemand helfen? danke im voraus.

+0

Minimale fehlende Nummer wo? Bei Null? Oder an der Mindestanzahl, die momentan in der Tabelle ist? –

+0

@DavidFaber - Letzteres (nach dem Code der OP gebucht). – mathguy

+0

@mathguy ... und auf leere Tabelle gibt 'NULL' zurück - um zu vermeiden, * negative Unendlichkeit * :) –

Antwort

0

Der beste Weg, um die Lücken zu finden, ist die Verwendung der analytischen Funktionen lead oder lag. Ein Beispiel mit lag:

with test_data as (
    select 1 num from dual union all 
    select 4 from dual union all 
    select 6 from dual union all 
    select 8 from dual union all 
    select 3 from dual union all 
    select 9 from dual union all 
    select 0 from dual 
) 
select min(gap) min_gap 
from (
    select num, lag(num) over (order by num)+1 gap 
    from test_data 
    ) 
where num != gap 
;  
MIN_GAP 
------------------ 
       2 

Mehr darüber, wie die Lücken here

+0

zu verwenden funktioniert. Danke vielmals. –

+0

Ich bin froh, Ihnen zu helfen – 0xdb

1

In Oracle 12.1 und oben zu finden, können MATCH_RECOGNIZE schnell tun Arbeit dieser Art von Problemen:

Herausgegeben. Anfangs wählte ich die "nächste Nummer", wo eine Lücke existiert (im Beispiel der Wert 9). Aber das will das OP nicht, er will die erste fehlende Nummer (7 in diesem Fall). Ich bearbeitete, um die measures Klausel zu ändern, um die erste fehlende Nummer wie angefordert zu finden. Ende bearbeiten

with test_data (num) as ( 
     select 4 from dual union all 
     select 5 from dual union all 
     select 6 from dual union all 
     select 9 from dual union all 
     select 10 from dual union all 
     select 13 from dual 
    ) 
-- end of test data; when you use the SQL query below, 
-- replace test_data and num with your actual table and column names. 
select result as num 
from test_data 
match_recognize (
    order by num 
    measures last(b.num) + 1 as result 
    pattern (^ a b* c) 
    define b as num = prev(num) + 1, 
     c as num > prev(num) + 1 
) 
; 

NUM 
--- 
    7 
+0

danke für die Lösung meines Problems –

2

Mit LEAD analytische Funktion können Sie die Nummer aus der nächsten Reihe aufsteigend erhalten. Vergleicht man diesen Wert mit der ursprünglichen Nummer um 1 erhöht man die fehlenden Werte (wenn zwei Zahlen nicht übereinstimmen).

zu dem ersten fehlenden Wert aufsteigend erhalten das gleiche ist, den MIN Wert Auswahl:

select 
num, 
lead(num) over (order by num) num_lead, 
case when num + 1 != lead(num) over (order by num) then num + 1 end as missing_num 
from test_data 
order by num; 

     NUM NUM_LEAD MISSING_NUM 
---------- ---------- ----------- 
     4   5    
     5   6    
     6   9   7 
     9   10    
     10   13   11 
     13       


-- first missing number = MIN missing number 
select min(missing_num) 
from (
select 
case when num + 1 != lead(num) over (order by num) then num + 1 end as missing_num 
from test_data 
); 

MIN(MISSING_NUM) 
---------------- 
       7 

NACHTRAGS

Eine gute Praxis SQL in schriftlicher Form ist Rand Fälle zu betrachten - hier eine Tabelle das enthält ein komplettes Intervall ohne Löcher. Der erste fehlende Wert wird der Nachfolger der letzten Nummer sein.

select nvl(min(missing_num),max(num)+1) first_missing_value 
from (
select 
num, 
case when num + 1 != lead(num) over (order by num) then num + 1 end as missing_num 
from test_data 
); 

Eine vollständige Tabelle keine MISSING_NUM zurückkehren, so die ursprüngliche Abfrage Rückkehr NULL. Unter Verwendung des NVL wird das erwartete Ergebnis bereitgestellt.

+0

Vielen Dank für die Hilfe bei der Lösung meines Problems –

+0

Sie sind herzlich willkommen @MuhammadYasir, können Sie auch die Antwort akzeptieren, wenn es hilfreich war :) –