Postgres:按字符串的一部分订购数据

Dzi*_*mid 10 sql postgresql

我有一个列名,代表一个人的姓名,格式如下:

firstname [middlename] lastname [, Sr.|Jr.]
Run Code Online (Sandbox Code Playgroud)

例如:

John Smith
John J. Smith
John J. Smith, Sr.
Run Code Online (Sandbox Code Playgroud)

如何通过姓氏订购商品?

Erw*_*ter 10

一个正确的和更快的版本看起来是这样的:

SELECT *
FROM   tbl
ORDER  BY substring(name, '([^[:space:]]+)(?:,|$)')
Run Code Online (Sandbox Code Playgroud)

要么:

ORDER  BY substring(name, E'([^\\s]+)(?:,|$)')
Run Code Online (Sandbox Code Playgroud)

甚至:

ORDER  BY substring(name, E'([^\\s]+)(,|$)')
Run Code Online (Sandbox Code Playgroud)

说明

[^[:space:]]+..由一个或多个非空白字符组成的第一个(也是最长的)字符串.
(,|$)..以逗号或字符串结尾终止.

最后两个示例使用了escape-string语法和class-shorthand\s而不是long形式[[:space:]](在字符类内部时丢失了括号的外层).

在我们想要提取的部分(?:) 之后,我们实际上不必使用非捕获括号,因为(引用手册):

..如果模式包含任何括号,则返回与第一个带括号的子表达式(左括号首先出现的那个)匹配的文本部分.

测试

SELECT substring(name, '([^[:space:]]+)(?:,|$)')
FROM  (VALUES 
  ('John Smith')
 ,('John J. Smith')
 ,('John J. Smith, Sr.')
 ,('foo bar Smith, Jr.')
) x(name)
Run Code Online (Sandbox Code Playgroud)