using labkey SQL to calculate next ID in a series

LabKey Support Forum (Inactive)
using labkey SQL to calculate next ID in a series Ben Bimber  2011-06-20 14:13
Status: Closed
 
We number our animals with a 1-2 digit string prefix followed by a number. the total string length is 6.

When people enter new IDs, I'd like them to supply a string prefix, and write a SQL string to calculate the next ID in the series. The difficultly is that IDs can either be 1 character + 5 digits or 2 / 4. the patterns are:

rhXXXX
rXXXXX
cyXXXX

In a similar situation elsewhere I did this:

SELECT cast(SUBSTRING(MAX(Id), "+prefix.length+", 6) AS INTEGER) as number FROM study.Demographics d WHERE Id LIKE '" + prefix + "%'"

However, this breaks down b/c if the prefix is 'r', it will return IDs starting with both 'r' or 'rh'. the substring function throws an error. are there other ways to approach this? some questions i had were:

1. without using a regular expression, can I make a smarter pattern matching in the WHERE clause than i'm doing?
2. is there a way to write "d.Id like 'r% AND 'the rest of the ID is numeric'" in labkey SQL?
3. assuming I cannot write a smarter WHERE clause, can I approach the SUBSTRING better?

Note: I'm passing this to JS code, so I could do some processing there. I'd like to offload whatever I can to SQL if possible though. I was considering something like:

SELECT SUBSTRING(MAX(Id), "+prefix.length+", 6) as max, SUBSTRING(min(Id), "+prefix.length+", 6) as min,FROM study.Demographics d WHERE Id LIKE '" + prefix + "%'"

then let the client take these 2 values and figure out which to use. this or something similar might work, but it seems fragile.
 
 
Ben Bimber responded:  2011-06-20 14:28
i dont know what i was thinking with that second SQL idea. please ignore that. any insight into sorting out the character vs digit portion of a string would still be appreciated. thanks.
 
Ben Bimber responded:  2011-06-20 15:10
i didnt realize the postgres pass-through function included some regular expression functions. this seems to works ok. the purpose of the ucase() = lcase() in the WHERE clause is a proxy for whether the substring has characters or not. i'd still be curious to know if there's a better way to do that.

var sql = "
SELECT max(regexp_replace(SUBSTRING(Id, "+(prefix.length+1)+", 6), '[a-z]+', '')) as maxNumber
FROM study.Demographics
WHERE Id LIKE '" + prefix + "%' AND lcase(SUBSTRING(Id, "+(prefix.length+1)+", 6)) = ucase(SUBSTRING(Id, "+(prefix.length+1)+", 6))";
 
trent responded:  2011-06-21 16:48
Another technique I've seen to remove alpha characters;

translate(val,translate(val, '1234567890',''),'')

where val is the column containing the data.

So,

select max(translate(val,translate(val, '1234567890',''),'')) as MAX_ID
from table

Ta,
Trent
 
jeckels responded:  2011-06-22 18:23
Hi Ben,

Be sure that if you're doing a MAX, you're doing it on a number and not a string. '9' > '100000'

Thanks,
Josh