Finding the lowest unused number after zero (so starting with 1), tested in sqlite but should work in mariadb/mysql also:
SELECT bicyclenumber + 1 FROM bicycles outertable WHERE NOT EXISTS ( SELECT NULL FROM bicycles innertable WHERE innertable.bicyclenumber = outertable.bicyclenumber + 1 AND innertable.owner = 321 ) AND outertable.owner = 321 UNION SELECT 1 AS bicyclenumber WHERE NOT EXISTS ( SELECT NULL FROM bicycles WHERE bicyclenumber = 1 AND owner = 321 ) ORDER BY bicyclenumber LIMIT 1
This works to give every user their own set of numbers that will track an individual bicycle. When a bicycle row is deleted, the gap will be reused, also when the first bicycle is deleted (in contrast to the top answer, which will not work when there is no data yet and be ever-increasing unless the first entry is never removed).
Usage
You can place this between () to make it a subquery and use it in an insert like so:
INSERT INTO bicycles (owner, bicyclenumber, name) VALUES(321, (...), 'Quicksilver')
Where ... is replaced with the giant query above. I need it in two different queries so made the subquery a PHP variable, though that feels quite ugly (better solutions are welcome).
Customisations
- If you do not need to have it per-user, just remove any part that says
AND owner = 321 - If you want to start at
0 or a different number, replace SELECT 1 and WHERE filternumber = 1 with the desired number
LAG(id, 1, null)function withOVER (ORDER BY id)clause.