[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Oct 2003
    Beiträge
    117

    SQL-Abfrage: Lücke finden

    Das Problem ist folgendes:

    In einer Tabelle gibt es unter anderem die Spalte LaufendeNummer.
    Sie kann die Werte 1-999 enthalten. Jede Nummer kann nur einmal vorkommen. Nicht alle Werte sind vorhanden.

    Jetzt brauche ich als Rückgabewert eines SQL-Statements die erste (kleinste) nicht verwendete LaufendeNummer.

    Beispiel:

    Inhalt der Spalte:
    001
    002
    003
    009
    010
    012
    013
    etc.

    Die SQL-Abfrage soll mir die 4 liefern.

    Jemand eine Idee?

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.243
    Für solche Aktionen habe ich mir eine kleine Hilfstabelle mit allen Zahlen von 1 bis gewünschtem Maximum erstellt (in diesem Fal von 1 - 999.999).

    Per

    Select MyNum from MyHelp H
    where not exists (select * from MyTable T where H.MyNum = T.NumField)
    fetch first row only

    Das Risiko der Doppelbelegung bei Parallelausführung habe ich über Sperren verhindert.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Oct 2003
    Beiträge
    117
    Danke so etwas Ähnliches hatte ich mir auch überlegt.

    Habe gerade noch eine andere Lösung:

    select min(LaufendeNummer) +1 from tabelle a where not exeists ( select * from tabelle b where .... and a.LaufendeNummer +1 = b.LaufendeNummer)

    Scheint zu funktionieren.

  4. #4
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    Wenn Du auf Release V5R4 oder höher bist, kannst Du auch wie folgt vorgehen:

    Code:
    With Counter (Nbr) as (   Select 1 from SysIbm/SysDummy1
                           Union All
                              Select Nbr + 1 from Counter
                                 Where Nbr < 1000)
    Select Min(Nbr) 
       from Counter exception join MyTable on Nbr = LfdNbr;;
    Ab 6.1 kannst du anstatt SysIbm/SysDummy1 auch Values verwenden:
    Code:
    With Counter (Nbr) as (Values(1)
                           Union All
                              Select Nbr + 1 from Counter
                                 Where Nbr < 1000)
    Select Min(Nbr) 
       from Counter exception join MyTable where Nbr = LfdNbr;;

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  5. #5
    Registriert seit
    Oct 2003
    Beiträge
    117
    Hallo Birgitta,

    Deine Lösung für 6.1 gefällt mir und funktioniert auch sehr gut ... vorausgesetzt man ersetzt das "where" durch "on" ;-).

    Die Lösung ist sicher auch performanter.

    Vielen Dank dafür.
    LG Allrounder

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.243
    Performant ist relativ.
    Für 100 Sätze über Value mag das wohlstimmen, für 1.000.000 Sätze eher unwahrscheinlich.
    Zu bedenken ist, dass nämlich die rekursive CTE erst komplett aufgebaut werden muss und ggf. ein temporärer Index erstellt wird (soweit das bei internen *QUERY-Objekten überhaupt passiert).
    Hat man diese aber als Ergebnis bereits verfügbar, dürfte das mit Tabelle schneller gehen.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    Zitat Zitat von Allrounder Beitrag anzeigen
    Hallo Birgitta,

    Deine Lösung für 6.1 gefällt mir und funktioniert auch sehr gut ... vorausgesetzt man ersetzt das "where" durch "on" ;-).

    Die Lösung ist sicher auch performanter.

    Vielen Dank dafür.
    LG Allrounder
    Sorry, kommt davon, wenn man ein SQL statement gerade mal schnell runterklimpert ohne auszuprobieren

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  8. #8
    Registriert seit
    Oct 2003
    Beiträge
    117
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Performant ist relativ.
    Für 100 Sätze über Value mag das wohlstimmen, für 1.000.000 Sätze eher unwahrscheinlich.
    Zu bedenken ist, dass nämlich die rekursive CTE erst komplett aufgebaut werden muss und ggf. ein temporärer Index erstellt wird (soweit das bei internen *QUERY-Objekten überhaupt passiert).
    Hat man diese aber als Ergebnis bereits verfügbar, dürfte das mit Tabelle schneller gehen.
    Ich meinte auch performanter als meine Lösung mit der "mit sich selbst gejointen" Tabelle. Eine Tabelle mit den Werten 1 - 999 permanent anzulegen, könnte wirklich schneller sein, mit Birgittas Lösung spare ich ein Objekt.
    Die Performance werde ich im Auge behalten.

    Nochmals vielen Dank euch beiden.

Similar Threads

  1. Einfache Abfrage in COBOL/400 mit EXEC SQL
    By AS400-Anfänger in forum NEWSboard Programmierung
    Antworten: 6
    Letzter Beitrag: 27-06-06, 13:18
  2. Abfrage nach <> Ziffern in SQL
    By behmer in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 29-05-06, 12:52
  3. sql abfrage
    By steven_r in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 17-05-06, 15:49
  4. Problem bei Abfrage bei Imbedded SQL
    By cbe in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 08-06-05, 16:21
  5. sql abfrage mit substring
    By juergenkemeter in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 17-11-04, 14:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •