I almost agree with Shyam except for that horribly convoluted function.
I recommend this query:
SELECT SUBSTRING_INDEX(reference,'/',-1) as `max`
FROM `Elements`
WHERE reference LIKE 'AES/JN/%'
ORDER BY reference DESC
LIMIT 1
This will output a single row with with 2003
as the value in the max
column.
The reason I like this method is because CONVERT()
is omitted/unnecessary.
I've compared my query against Xenofexs' on my server and mine is only .0001
seconds faster -- but this is only running on the 5 rows that the OP posted. As the database volume increases, I am confident that my query's performance lead will increase.
Even if you don't care about the micro-optimization, I think this query is easier to read/comprehend because it doesn't have a function inside a function inside a function.
In fact, I believe this next query may outperform my above query:
SELECT SUBSTRING_INDEX(reference,'/',-1) as `max`
FROM `Elements`
WHERE LOCATE('AES/JN/',reference)
ORDER BY reference DESC
LIMIT 1
Because LOCATE()
will be checking the leading characters from the reference
column, and the targeted substring will not occur later in the string, LOCATE()
has been benchmarked to outperform LIKE
.
Additional reading:
MySQL LIKE vs LOCATE
For the record, here is the table that I used:
CREATE TABLE `Elements` (
`id` int(10) NOT NULL,
`reference` varchar(100) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `Elements` (`id`, `reference`) VALUES
(101, 'AES/JN/2001'),
(102, 'AMES/JN/2001'),
(103, 'AES/JN/2002'),
(104, 'AES/JN/2003'),
(105, 'AMES/JN/2002');
ALTER TABLE `Elements`
ADD PRIMARY KEY (`id`);
ALTER TABLE `Elements`
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=106;