SQL: Nächste freie ID (nicht MaxID)
Autor: Ralf v.d.Mark
eingetragen: Donnerstag, 14. März 2019 um 12:38 Uhr (11/2019 Kalenderwoche)
geändert: Freitag, 15. März 2019 um 10:28 Uhr (11/2019 Kalenderwoche)
Keywords: NextFreeId NextFreeKey nächste primary
Kategorien: DB: MySQL, DB: MariaDB,
Text:
Das Problem: Zwei Anwendungen mit unterschiedlichen DB-Tabellen vereint werden soll, schreibt man manchmal die fremde ID in die ID-Spalte (Primary) der anderen Tabelle. Damit es keine Kollisionen gibt, stellt man einen ID-Bereich für die Fremd-IDs zur Verfügung.
Wenn dann dieser Bereich knapp wird, möchte man die freien Plätze nutzen.
Dazu ist die SQL-Abfrage praktisch, die einem die nächste freie ID (als "NextFreeKey") liefert.
Quellcode:
SELECT t1.vproj_id + 1 AS NextFreeKey
FROM anmldg_veranst_proj t1
LEFT JOIN anmldg_veranst_proj t2
ON (t2.vproj_id = t1.vproj_id + 1)
WHERE t2.vproj_id IS NULL
ORDER BY t1.vproj_id ASC
LIMIT 1;
-------------------------------------------
SELECT (vproj_id + 1) AS NextFreeKey
FROM anmldg_veranst_proj
WHERE (vproj_id + 1) NOT IN (
SELECT vproj_id
FROM anmldg_veranst_proj)
ORDER BY NextFreeKey
LIMIT 1
-------------------------------------------
-- Bei 2 Tabellen: Funktioniert,
-- findet aber nicht jede freie ID!!
SELECT t1.vproj_id + 1 AS NextFreeKey
FROM anmldg_veranst_proj t1
LEFT JOIN anmldg_veranst_proj t2
ON (t2.vproj_id = t1.vproj_id + 1)
LEFT JOIN ipa_einrichtg t3
ON (t3.einrchtg_id = t1.vproj_id + 1)
WHERE t2.vproj_id IS NULL
AND t3.einrchtg_id IS NULL
ORDER BY t1.vproj_id ASC
LIMIT 1;
-------------------------------------------
-- Bei 2 Tabellen:
-- Besser ist PHP zur Hilfe zu nehmen:
SELECT t1.vproj_id AS ProjKey
FROM anmldg_veranst_proj AS t1
ORDER BY t1.vproj_id ASC
LIMIT 1000;
SELECT t1.einrchtg_id AS EinrKey
FROM ipa_einrichtg AS t1
ORDER BY t1.einrchtg_id ASC
LIMIT 1000;
-- ...und das Ergebnis mit PHP zu loopen:
for ($zaehler = 10; $zaehler <= 1000; $zaehler++) {
if (empty($result[$zaehler]['ProjKey']) && empty($resultEinr[$zaehler]['EinrKey'])) {
//Wenn beide leer sind, dann kann der Key genommen werden!!
return $zaehler;
break;//ist eigentlich schon beendet, aber ... ;-)
}//ENDE: if (!empty($result)
}//ENDE: for ($zaehler = 1; $zaehler <= 1000; $zaehler++)
return false;