Short answer -- use this query:
SELECT id AS PrevID, CONCAT(
SUBSTRING(id, 1, 4),
IF(CAST(SUBSTRING(id, 5) AS UNSIGNED) <= 9, '0', ''),
CAST(SUBSTRING(id, 5) AS UNSIGNED) + 1
) AS NextID
FROM (
-- since you allow strings such as AAAA20 and AAAA100 you can no longer use MAX
SELECT id
FROM t
ORDER BY SUBSTRING(id, 1, 4) DESC, CAST(SUBSTRING(id, 5) AS UNSIGNED) DESC
LIMIT 1
) x
Results:
| PrevID | NextID |
| AAAA100 | AAAA101 |
| AAAA21 | AAAA22 |
| AAAA06 | AAAA07 |
Just for the fun, I wrote this stored procedure that generates numbers that look like AAAA00 AAAA99 AAAB00 etc:
CREATE FUNCTION NextID(PrevID VARCHAR(6))
RETURNS VARCHAR(6)
BEGIN
DECLARE s VARCHAR(4);
DECLARE i INT;
DECLARE j INT;
SET s = LEFT(PrevID, 4);
SET s = REPLACE(s, 'A', '0');
SET s = REPLACE(s, 'B', '1');
SET s = REPLACE(s, 'C', '2');
SET s = REPLACE(s, 'D', '3');
SET s = REPLACE(s, 'E', '4');
SET s = REPLACE(s, 'F', '5');
SET s = REPLACE(s, 'G', '6');
SET s = REPLACE(s, 'H', '7');
SET s = REPLACE(s, 'I', '8');
SET s = REPLACE(s, 'J', '9');
SET s = REPLACE(s, 'K', 'A');
SET s = REPLACE(s, 'L', 'B');
SET s = REPLACE(s, 'M', 'C');
SET s = REPLACE(s, 'N', 'D');
SET s = REPLACE(s, 'O', 'E');
SET s = REPLACE(s, 'P', 'F');
SET s = REPLACE(s, 'Q', 'G');
SET s = REPLACE(s, 'R', 'H');
SET s = REPLACE(s, 'S', 'I');
SET s = REPLACE(s, 'T', 'J');
SET s = REPLACE(s, 'U', 'K');
SET s = REPLACE(s, 'V', 'L');
SET s = REPLACE(s, 'W', 'M');
SET s = REPLACE(s, 'X', 'N');
SET s = REPLACE(s, 'Y', 'O');
SET s = REPLACE(s, 'Z', 'P');
SET i = RIGHT(PrevID, 2);
SET j = CONV(s, 26, 10);
SET i = i + 1;
IF i > 99 THEN
SET i = 0;
SET j = j + 1;
END IF;
SET s = CONV(j, 10, 26);
SET s = REPLACE(s, 'P', 'Z');
SET s = REPLACE(s, 'O', 'Y');
SET s = REPLACE(s, 'N', 'X');
SET s = REPLACE(s, 'M', 'W');
SET s = REPLACE(s, 'L', 'V');
SET s = REPLACE(s, 'K', 'U');
SET s = REPLACE(s, 'J', 'T');
SET s = REPLACE(s, 'I', 'S');
SET s = REPLACE(s, 'H', 'R');
SET s = REPLACE(s, 'G', 'Q');
SET s = REPLACE(s, 'F', 'P');
SET s = REPLACE(s, 'E', 'O');
SET s = REPLACE(s, 'D', 'N');
SET s = REPLACE(s, 'C', 'M');
SET s = REPLACE(s, 'B', 'L');
SET s = REPLACE(s, 'A', 'K');
SET s = REPLACE(s, '9', 'J');
SET s = REPLACE(s, '8', 'I');
SET s = REPLACE(s, '7', 'H');
SET s = REPLACE(s, '6', 'G');
SET s = REPLACE(s, '5', 'F');
SET s = REPLACE(s, '4', 'E');
SET s = REPLACE(s, '3', 'D');
SET s = REPLACE(s, '2', 'C');
SET s = REPLACE(s, '1', 'B');
SET s = REPLACE(s, '0', 'A');
RETURN CONCAT(LPAD(s, 4, 'A'), LPAD(i, 2, '0'));
END
SELECT NextID('AAAA01') -- AAAA02
SELECT NextID('AAAA99') -- AAAB00
SELECT NextID('AAAB99') -- AAAC00
SELECT NextID('AAAZ99') -- AABA00
mainode(btw, s that meant to be "mainnode" or "maincode"?) which contains the "AAAA" prefix. So can't you just have a numeric field that autoincrements at access and return a concatenation of both?SELECT MAX(s) FROM (SELECT 'AAAA100' s UNION SELECT 'AAAA21') xreturnsAAAA21!!!