确定列值中最后一个大写字母的索引 (SQL)?

Determining index of last uppercase letter in column value (SQL)?

简短版本: 有没有一种方法可以根据该值的最后一个大写字母, 使用SQL?

长版: 我有一个带有用户名字段的 table,用户名的约定是名字的首字母大写,后面是大写姓氏的第一个首字母,然后是姓氏的其余部分。因此,按用户名字段排序是 'wrong'。按用户名值的子字符串排序在理论上是可行的,例如

SUBSTRING(username,2, LEN(username))

...除了在其他两个首字母之间有一个大写的中间首字母的值。我很想知道,仅使用 SQL(MS SQL 服务器)是否有一种相当直接/简单的方法:

  1. 测试 DB 值中字符的大小写(以及 return 布尔值)
  2. 确定字符串值中最后一个大写字符的索引

假设这甚至是遥不可及的,我假设必须循环遍历每个用户名的各个字母才能完成它,这使得它非常低效,但如果你有一个神奇的捷径,请随时分享。 注意:这个问题纯粹是学术性的,因为我已经决定采用更简单的方法。我只是好奇这是否可能。

  1. Test the case of a character in a DB value (and return a boolean)

SQL 服务器没有布尔数据类型。 bit 经常被用来代替它。

DECLARE @Char CHAR(1) = 'f'

SELECT CAST(CASE
              WHEN @Char LIKE '[A-Z]' COLLATE Latin1_General_Bin
                THEN 1
              ELSE 0
            END AS BIT) 
 /* Returns 0 */

请注意,在上述语法中使用二进制排序规则而不是区分大小写的排序规则子句很重要。如果使用 CS 整理子句,则需要将模式完整拼写为 '[ABCDEFGHIJKLMNOPQRSTUVWXYZ]' 以避免匹配小写字符。

  1. Determine the index of the last upper case character in a string value
SELECT PATINDEX('%[A-Z]%' COLLATE Latin1_General_Bin, REVERSE('Your String'))
/* Returns one based index (6 ) */

SELECT PATINDEX('%[A-Z]%' COLLATE Latin1_General_Bin, REVERSE('no capitals'))
/* Returns 0 if the test string doesn't contain any letters in the range A-Z */
  1. To extract the surname according to those rules you can use
SELECT RIGHT(Name,PATINDEX('%[A-Z]%' COLLATE Latin1_General_Bin ,REVERSE(Name)))
FROM YourTable