SQL: Nächste freie ID (nicht MaxID)

edit | delete

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;