matt1234: [MySQL] Nächster freier Wert in Integer Spalte

Hallo,

wie die Überschrift schon verrät, möchte ich aus einer MySQL Spalte (Typ Integer) den nächsten freien Wert erhalten.

Inhalt:
Zahl (int)
1000
1001
1002
1004
1005
1010

Gewünschtes Ergebnis ist dann 1003 (da noch nicht vergeben).
Kann mir jemand weiterhelfen oder einen Tip geben?

Mein Grundgerüst ist ein LEFT JOIN mit sich selbst, hier scheine ich jedoch einen logischen Fehler zu haben.

VG
Matt

  1. Hi,

    wie die Überschrift schon verrät, möchte ich aus einer MySQL Spalte (Typ Integer) den nächsten freien Wert erhalten.

    sowas ist für Datenbanktechniken kein Use-Case, deswegen kannst Du auch keine entsprechende Implementierung erwarten. Der wesentliche Fall, in dem die Datenbank einen nicht benutzen Wert ermitteln muss, sind IDs, und deren expliziter Wert ist zu exakt 100% absolut und uneingeschränkt vollkommen egal. Er kann von "1" über "pi" direkt zu "Wurstbrot" gehen, auch wenn "finanziell unausgelastet" noch dazwischen passt.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
  2. Hello,

    wie die Überschrift schon verrät, möchte ich aus einer MySQL Spalte (Typ Integer) den nächsten freien Wert erhalten.

    Inhalt:
    Zahl (int)
    1000
    1001
    1002
    1004
    1005
    1010

    Gewünschtes Ergebnis ist dann 1003 (da noch nicht vergeben).
    Kann mir jemand weiterhelfen oder einen Tip geben?

    suche im hiesigen Archiv nach "Lücken finden"
    http://forum.de.selfhtml.org/archiv/2008/4/t170280/#m1112995

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
  3. Hallo,

    wie die Überschrift schon verrät, möchte ich aus einer MySQL Spalte (Typ Integer) den nächsten freien Wert erhalten.

    Zahl (int)
    1000
    1001
    1002
    1004
    1005
    1010

    Gewünschtes Ergebnis ist dann 1003 (da noch nicht vergeben).
    Kann mir jemand weiterhelfen oder einen Tip geben?

    Nummeriere die Datensätze durch und schau nach, wann die Nummerierungsspalte kleinere Werte enthält als die Zahlspalte:

    1. Schritt: Durchnummerierung

      
    SET @a = 999;                -- Setze die Benutzervariable auf einen Wert, der  
                                 -- um 1 kleiner ist als Dein Startwert.  
    SELECT  
        @a := (@a + 1) zaehler,  -- Nummerierungsspalte  
        Zahl  
    FROM  
        tabelle  
    ORDER BY                     -- aufsteigend nach der Zahl-Spalte sortiert  
        Zahl  
    
    

    2. Schritt: Den Datensatz anzeigen, bei dem die erste Abweichung auftritt.
                Beim Auftreten einer Lücke ist der Wert in der Spalte Zahl
                größer als der in der Nummerierungsspalte.

    SET @a = 999;                -- Setze die Benutzervariable auf einen Wert, der  
                                 -- um 1 kleiner ist als Dein Startwert.  
    SELECT  
        vergleich.zaehler  
    FROM (  
        SELECT  
            @a := (@a + 1) zaehler,  -- Nummerierungsspalte  
            Zahl  
        FROM  
            tabelle  
        ORDER BY                     -- aufsteigend nach der Zahl-Spalte sortiert  
            Zahl  
    ) vergleich                  -- Name für die Unterabfrage  
    WHERE  
        vergleich.zaehler < Zahl  
    LIMIT 1                      -- Nur die erste Lücke finden.  
      
    
    

    Beachte:
    Wenn es keine Lücke gibt, liefert die Abfrage keinen Datensatz zurück.

    Ach ja:
    Irgendwelche Lücken in Spalten, die nur die Identifikation dienen, sind völlig normal und verdienen keinerlei Beachtung.

    Wozu willst Du diesen Wert ermitteln. Um diesen für einen neuen Datensatz zu verwenden. Wenn ja, so ist dies keine gute Idee. Verwende lieber eine auto_increment-Spalte für sowas.

    Willst Du es dennoch tun, so sorge dafür, dass Du das Ausfindigmachen dieses Wertes und die Verwendung beim INSERT in eine atomare Aktion kapselst, um Dir keine Race-Condition (TOCTTOU-Problem, Time-of-check-to-time-of-use) einzuhandeln. Mit der Verwendung von auto_increment-Werten hast Du dieses Problem nicht. Bedenke außerdem, dass Du beim Löschen eines Datensatzes alle sich darauf beziehenden Datensätze in anderen Tabellen ebenfalls löschen musst (z.B. durch ON DELETE CASCADE), sonst handelst Du Dir kaputte Daten ein. Andererseits könntest Du Dir mit diesem Löschen ganz andere Probleme einhandeln, die die Nutzbarkeit Deiner Daten ebenfalls beeinträchtigen ...

    => Ich sehe keinen praktischen Nutzen im Lösen dieser Aufgabe.

    Freundliche Grüße

    Vinzenz

  4. Hi,

    Inhalt:
    Zahl (int)
    1000
    1001
    1002
    1004
    1005
    1010

    Gewünschtes Ergebnis ist dann 1003 (da noch nicht vergeben).
    Kann mir jemand weiterhelfen oder einen Tip geben?

    SELECT MIN(zahl) FROM table t1 WHERE NOT EXISTS(SELECT zahl FROM table t2 WHERE t2.zahl = t1.zahl + 1)

    (auf der Spalte Zahl sollte aus Performance-Gründen ein Index existieren).

    Wenn Du das benutzen willst, um ID-"Lücken" zu füllen: tu es nicht. IDs sollten nicht wiederverwendet werden.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.