kleinste freie Nummer in Tabellenspalte finden



  • Hallo,

    gibt es be MySql irgendwas um die kleinste freie Nummer im Bereich von 1 - 10000 in einer Tabellenspalte zu finden?

    Meine Tabelle hat die Form:

    Nummer     ...
    
    1          (Daten)
    3          (Daten)
    4          (Daten)
    5          (Daten)
    10         (Daten)
    999        (Daten)
    1000       (Daten)
    1001       (Daten)
    

    Kann ich irgendwie durch eine Query eine 2, also die erste freie Nummer erhalten, beim zweiten Mal dann eine 6(wenn ich die 2 in die Datenbank geschrieben habe) usw, oder muss ich das tatsächlich von Hand programmieren oder rumtricksen im Sinne von mal eine Tabelle mit den Werten 1 - 10000 erstellen und da dann draufjoinen?



  • Mal ne andere Frage: Wofür braucht man das? 😃

    Wenn man evtl. viele Datensätze zwischendrin löscht, dann entstehen Lücken in den IDs, schon klar, aber es kann ja immerhin sein, dass andere Tabellen auf diese referenzieren, wenn ich dann einfach die IDs ändere, dann gibt es ein heilloses Durcheinander.



  • Wenn das vorkommt hab ich eh mist gebaut, wenn dann lösche ich den gesamten Datensatz mit allen Untertabellen etc, weil sonst eh nur Datenmüll entsteht.

    Die Nummer repräsentiert halt die Respondernummer für ein Halsband, das so liebe milchgebende Tierchen umbekommen.
    Da die nicht billig und die Nummern fest eingespeichert sind, hat man nur begrenzt viele davon und dementsprechend, brauche ich immer die kleinste Lücke um einen sinnvollen Vorschlag für das Anlegen eines neuen Tieres zu machen.



  • Da ich leider nicht weiß, wie man das genau mit einem Statement umsetzen könnte, was Du möchtest, hier ein Vorschlag:

    Warum machst Du nicht eine Spalte, die angibt, ob der Datensatz frei ist, oder nicht, z.B. 'used'. Wenn Du einen Datensatz einträgst, dann setzt Du 'used' auf '1', wenn Du einen Datensatz "löscht", dann löscht Du nur die Daten raus, behälst ihn aber in der Tabelle und setzt 'used' auf '0'. Dann kannst Du mit

    select min(`id`) as `newid` from `table` where `used` = '0';
    

    die ID ermitteln, falls es eine gibt. Falls nicht, dann wird glaube ich NULL zurückgegeben, musst Du mal testen, in dem Fall fügst Du halt einen neuen Datensatz in die Tabelle ein.

    PS: lock / unlock table nicht vergessen. 🙂

    // Edit:
    Falls obiges Statement nicht läuft, dann müsste

    select `id` from `table` where `used` = '0' order by `id` asc limit 1;
    

    funzen. Da wird dann ein leeres Resultset zurückgeliefert, wenn es keine freie ID gibt.



  • Die Nummern können auch schon durcheinander ankommen, ich lade die aus einem Automaten über die serielle Schnittstelle und die Nummern können irgendwelche sein, wird das so nichts.

    Ich möchte halt beim anlegen eines Tieres die erste freie Tiernummer in der Datenbank ermitteln und dem Benutzer vorschlagen, also wenn irgendwo eine Lücke ist, dann soll diese vorgeschlagen werden, ist historisch bedingt, muss so sein und macht auch Sinn.

    Ich kann jetzt natürlich alle 10k Tiere anlegen mit frei flag oder mir eine Tabelle mit Nummern zwischen 1 und 10000 machen um damit zu joinen, damit würde es mit is null einfach gehen, aber die Frage ist halt ob es eleganter geht, zumal ich eine ähnliche Sache nocheinmal mit Zahlen zwischen 1 und 999999999999 habe, spätestens dann wird das böse.



  • SELECT MIN(ID+1) FROM Tabelle WHERE ID NOT IN (SELECT ID-1 FROM Tabelle);

    Kann deine Datenbank sowas ?



  • Das macht man nicht. Man fügt immer am Ende ein und wenn es tatsächlich mal sein müsste lässt man die DB reorganisieren.

    Alias: Benütze für die Ermittlung der nächsten ID eine Sequence, wenn dein DBMS das nicht unterstützt (zB MySQL, Access) dann unterstützen die meistens ein System namens AutoIncrement. Leider keine ordentliche Sequence aber immerhin.

    MfG SideWinder



  • cool, das läuft wie blöd, danke 😉

    Naja, das ist wiegesagt nur ein Eingabemaskenvorschlag und da diese Nummer halt fest ist, lässt sich das nicht anders lösen.
    Wenn ich eine Tabelle mit Personalausweisnummer als Primärschlüssel habe, kann ich auch nicht sagen "wenn die Nummer irgendwo zwischendrin steht, denke ich mir eine neue aus".
    Oder macht man dann immer eine aussagenlose ID um immer hochzählen zu können?

    Es ist auch keine Datenbank wo es so extrem auf Leistung ankommt, die benutze ich nur für die Anwendung und das in der Regel auch nur von einem Benutzer, war halt nur angenehmer damit die Datensätze, auch wenn es nur ein paar tausend sind, zu organisieren und zu übertragen.
    Da ist sowas vonwegen "das ist aber theoretisch doof langsam und bringt die DB Indizies durcheinander" eher reine Theorie, die nicht relevant ist.



  • dreaddy schrieb:

    cool, das läuft wie blöd, danke

    Dann ist es wohl auch nicht so schlimm, dass es nicht so ganz funktioniert, wenn die 1 fehlt (oder 1 bis 3)... 😃



  • das macht natürlich nichts, wie war das? "ist der Code erst ruiniert, frickelt sichs ganz ungeniert" oder so :>

    Halt eine Abfrage vorher ob 1 vorhanden ist, wenn ja dann obiges, wenn nein dann freie Nummer = 1 und gut is.
    Ich will das ja nicht benoten lassen, sondern für viel Geld verkaufen.

    Ne mal ernsthaft, ich bin für eine sauberere Lösung gern zu haben wenn es da noch was gibt, aber nicht wenn ich erstmal ne Woche lang die ganze Datenbank umbauen muss und nen Haufen jetzt gut funktionierenden Quellcode anfassen muss, nur damit der Kunde einmal am Tag eine Sekunde Zeit spart, andere Vorteile würd das nicht bringen.


Anmelden zum Antworten