[MySQL] Nächster freier Wert in Integer Spalte
matt1234
- datenbank
1 Cheatah0 Tom1 Vinzenz Mai0 MudGuard
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
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
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
1010Gewü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
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
1010Gewü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
Hi,
Inhalt:
Zahl (int)
1000
1001
1002
1004
1005
1010Gewü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