snippetsqlModerate
How To Remove Leading Characters in SQL
Viewed 0 times
leadingsqlremovehowcharacters
Problem
I have a table in SQL 2012 which we can call 'Table' for instance. It has items like this in it,
I would like to be able to do this,
And the result be this,
So it orders the items based on removing the leading underscore characters. It can't just blindly remove the underscore characters though because the underscores might be in the middle of the items.
For instance this does not work,
Column
_one
_two
three_blah
four_blahI would like to be able to do this,
select * from Table order by ColumnAnd the result be this,
four_blah
one
three_blah
twoSo it orders the items based on removing the leading underscore characters. It can't just blindly remove the underscore characters though because the underscores might be in the middle of the items.
For instance this does not work,
select Replace(Column, '_', '') from Table order by Replace(Column, '_', '')Solution
Assuming col caps out at 255 characters, this doesn't have to perform any checks on length or complicated case expressions:
Updating to show an example that works with varchar even if the value I hard-coded exceeds the size of the column:
Results:
Another alternative (that doesn't require hard-coding the length of the string or determining the length of every value in the table) is to use STUFF. Note that this does change how strings without a single alphabetic character will be handled (NULL output instead of being left alone). Those rows will still sort first, they'll just be less meaningful. You can deal with those however you like by adding
(This portion of the answer should be credited to @MikaelEriksson.)
SELECT col = SUBSTRING(col, PATINDEX('%[a-z]%', col), 255)
FROM dbo.table
ORDER BY col;Updating to show an example that works with varchar even if the value I hard-coded exceeds the size of the column:
DECLARE @t TABLE(col VARCHAR(32));
INSERT @t VALUES
('_one'),
('_two'),
('three_blah'),
('four_blah');
SELECT col = SUBSTRING(col, PATINDEX('%[A-Za-z]%', col), 255)
FROM @t
ORDER BY col;Results:
col
----------
four_blah
one
three_blah
twoAnother alternative (that doesn't require hard-coding the length of the string or determining the length of every value in the table) is to use STUFF. Note that this does change how strings without a single alphabetic character will be handled (NULL output instead of being left alone). Those rows will still sort first, they'll just be less meaningful. You can deal with those however you like by adding
COALESCE.SELECT col = STUFF(col, 1, PATINDEX('%[A-Za-z]%', col)-1, '')
FROM @t
ORDER BY col;(This portion of the answer should be credited to @MikaelEriksson.)
Code Snippets
SELECT col = SUBSTRING(col, PATINDEX('%[a-z]%', col), 255)
FROM dbo.table
ORDER BY col;DECLARE @t TABLE(col VARCHAR(32));
INSERT @t VALUES
('_one'),
('_two'),
('three_blah'),
('four_blah');
SELECT col = SUBSTRING(col, PATINDEX('%[A-Za-z]%', col), 255)
FROM @t
ORDER BY col;col
----------
four_blah
one
three_blah
twoSELECT col = STUFF(col, 1, PATINDEX('%[A-Za-z]%', col)-1, '')
FROM @t
ORDER BY col;Context
StackExchange Database Administrators Q#22553, answer score: 10
Revisions (0)
No revisions yet.