Wenn die Order
Spalte indiziert ist, können Sie die erste fehlende Zahl mit SQL bekommen, ohne die komplette Tabelle Lesen eines ohne LEFT mit JOIN:
SELECT t1.`Order` + 1 AS firstMissingOrder
FROM tabla t1
LEFT JOIN tabla t2 ON t2.`Order` = t1.`Order` + 1
WHERE t2.`Order` IS NULL
AND t1.`Order` <> (SELECT MAX(`Order`) FROM tabla)
ORDER BY t1.`Order`
LIMIT 1
oder (vielleicht intuitivere)
SELECT t1.`Order` + 1 AS firstMissingOrder
FROM tabla t1
WHERE NOT EXISTS (
SELECT 1
FROM tabla t2
WHERE t2.`Order` = t1.`Order` + 1
)
AND t1.`Order` <> (SELECT MAX(`Order`) FROM tabla)
ORDER BY t1.`Order`
LIMIT 1
Die zweite Abfrage wird von MySQL in die erste umgewandelt. Sie sind also praktisch gleichwertig.
aktualisieren
Erdbeere erwähnt einen guten Punkt: Die erste fehlende Zahl 1
sein könnte, die in meiner Anfrage nicht abgedeckt ist. Aber ich konnte keine Lösung finden, die beides ist - elegant und schnell.
Wir könnten den umgekehrten Weg gehen und nach einer Lücke nach der ersten Nummer suchen. Müsste aber wieder an den Tisch gehen, um die letzte existierende Nummer vor dieser Lücke zu finden.
MySQL (in meinem Fall MariaDB 10.0.19) ist nicht in der Lage, diese Abfrage richtig zu optimieren. Es dauert ungefähr eine Sekunde in einer indizierten (PK) 1M Zeilentabelle, obwohl die erste fehlende Zahl 9 ist. Ich würde erwarten, dass der Server die Suche nach t1.Order=10
aufhört, aber es scheint nicht so zu sein.
Eine andere Möglichkeit, die schnell ist, aber hässlich aussieht (IMHO), besteht darin, die ursprüngliche Abfrage in einem Subselect nur zu verwenden, wenn Order=1
existiert. Andernfalls geben Sie 1
zurück.
SELECT CASE
WHEN NOT EXISTS (SELECT 1 FROM tabla WHERE `Order` = 1) THEN 1
ELSE (
SELECT t1.`Order` + 1 AS firstMissingOrder
FROM tabla t1
LEFT JOIN tabla t2 ON t2.`Order` = t1.`Order` + 1
WHERE t2.`Order` IS NULL
AND t1.`Order` <> (SELECT MAX(`Order`) FROM tabla)
ORDER BY t1.`Order`
LIMIT 1
)
END AS firstMissingOrder
Oder UNION
SELECT 1 AS firstMissingOrder FROM (SELECT 1) dummy WHERE NOT EXISTS (SELECT 1 FROM tabla WHERE `Order` = 1)
UNION ALL
SELECT firstMissingOrder FROM (
SELECT t1.`Order` + 1 AS firstMissingOrder
FROM tabla t1
LEFT JOIN tabla t2 ON t2.`Order` = t1.`Order` + 1
WHERE t2.`Order` IS NULL
AND t1.`Order` <> (SELECT MAX(`Order`) FROM tabla)
ORDER BY t1.`Order`
LIMIT 1
) sub
LIMIT 1
Hinweis helfen, dass, um ein reserviertes Wort ist - und warum nicht die Nummer 0? – Strawberry
danke Bestellung ist ein Beispiel, nur Zahlen> 0. Ich habe eine neue Antwort Dinamic –