如何删除 SQL 中的前导字符

pet*_*ter 4 sql-server

例如,我在 SQL 2012 中有一个表,我们可以将其称为“表”。里面有这样的物品,

Column

_one
_two
three_blah
four_blah
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这一点,

select * from Table order by Column
Run Code Online (Sandbox Code Playgroud)

结果是这样的

four_blah
one
three_blah
two
Run Code Online (Sandbox Code Playgroud)

因此,它根据删除前导下划线字符对项目进行排序。它不能只是盲目地删除下划线字符,因为下划线可能位于项目的中间。

例如这不起作用,

select Replace(Column, '_', '') from Table order by Replace(Column, '_', '')
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 10

假设 col 上限为 255 个字符,则不必对长度或复杂的 case 表达式执行任何检查:

SELECT col = SUBSTRING(col, PATINDEX('%[a-z]%', col), 255)
  FROM dbo.table
  ORDER BY col;
Run Code Online (Sandbox Code Playgroud)

更新以显示一个适用于 varchar 的示例,即使我硬编码的值超过了列的大小:

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;
Run Code Online (Sandbox Code Playgroud)

结果:

col
----------
four_blah
one
three_blah
two
Run Code Online (Sandbox Code Playgroud)

另一种替代方法(不需要硬编码字符串的长度或确定表中每个值的长度)是使用 STUFF。请注意,这确实改变了没有单个字母字符的字符串的处理方式(NULL 输出而不是单独留下)。这些行仍将首先排序,只是意义不大。您可以通过添加COALESCE.

SELECT col = STUFF(col, 1, PATINDEX('%[A-Za-z]%', col)-1, '')
  FROM @t
  ORDER BY col;
Run Code Online (Sandbox Code Playgroud)

(这部分答案应归功于@MikaelEriksson。)