A cycle on a busy table will be very unlikely to be completed. Use REVERSE and PATINDEX to find the first digit, start OPEN there, and then UNLOCK the result. It will be rather slow, without cycles.
Your examples assume that you also do not want to match spaces.
DECLARE @t TABLE (s NVARCHAR(500)) INSERT INTO @t (s) VALUES ('Hi there how are you'),('What is the #1 pizza place in NYC?'),('Dominoes is number 1'),('Blah blah 123123'),('More blah 12321 123123 123132') select s , reverse(s) as beginning , patindex('%[^0-9 ]%',reverse(s)) as progress , substring(reverse(s),patindex('%[^0-9 ]%',reverse(s)), 1+len(s)-patindex('%[^0-9 ]%',reverse(s))) as [more progress] , reverse(substring(reverse(s),patindex('%[^0-9 ]%',reverse(s)), 1+len(s)-patindex('%[^0-9 ]%',reverse(s)))) as SOLUTION from @t
Final answer: reverse (substring (reverse (@s), patindex ('% [^ 0-9]%', reverse (@s)), 1 + len (@s) - patindex ('% [^ 0-9 ]% ', reverse (@s))))
bsdfm
source share