设置Order By以忽略每列的标点符号

时间:2013-07-01 18:00:14

标签: postgresql sql-order-by postgresql-9.1 collation

是否可以通过包含[](),;等字符的标题字段来排序PostgreSQL查询的结果,但忽略这些标点符号并仅按文本字符排序?

我读过有关更改数据库排序规则或区域设置的文章,但没有找到关于如何在每个列的现有数据库上执行此操作的明确说明。这甚至可能吗?

2 个答案:

答案 0 :(得分:5)

“Normalize”用于排序

可以regexp_replace()子句中使用'[^a-zA-Z]'格式ORDER BY,但只能识别纯ASCII字母。更好地使用class shorthand '\W'识别您的语言环境中的其他非ASCII字母,例如äüóèß等。 或者你可以即兴创作并在unaccent()函数的帮助下将带变音元素的所有字符规范化为基本形式。考虑一下这个小演示:

SELECT *
      , regexp_replace(x, '[^a-zA-Z]', '', 'g')
      , regexp_replace(x, '\W', '', 'g')
      , regexp_replace(unaccent(x), '\W', '', 'g')
FROM  (
SELECT 'XY ÖÜÄöüäĆČćč€ĞğīїıŁłŃńŇňŐőōŘřŠšŞşůŽžż‘´’„“”­–—[](),;.:̈� XY'::text AS x) t

->SQLfiddle for Postgres 9.2.
->SQLfiddle for Postgres 9.1.

正则表达式代码已在9.2版中更新。我假设这是9.2中改进处理的原因,其中示例中的所有字母字符都匹配,而9.1只匹配一些。

unaccent()由附加模块unaccent提供。运行:

CREATE EXTENSION unaccent;

每个数据库使用一次(Postgres 9.1+,旧版本使用different technique)。

locales / collat​​ion

您必须知道Postgres依赖于语言环境的底层操作系统(包括排序规则)。排序顺序由您选择的区域设置或更具体的LC_COLLATE决定。更多相关答案:
String sort order (LC_COLLATE and LC_CTYPE)

plans to incorporate collation support into Postgres directly,但目前无法使用。

许多语言环境会忽略您描述的用于对字符数据进行排序的特殊字符。如果系统中安装了提供所需排序顺序的语言环境,则可以在Postgres 9.1或更高版本中临时使用它:

SELECT foo FROM bar ORDER BY foo COLLATE "xy_XY"

要查看当前Postgres安装中安装和可用的排序规则:

SELECT * FROM pg_collation;

不幸的是,除非您破解源代码,否则无法定义您自己的自定义归类。

整理规则通常由一个国家/地区使用的语言规则管理。电话簿的排序顺序,如果还有电话簿......你的操作系统提供它们。

例如,在Debian Linux中你可以使用:

locale -a

显示所有生成的区域设置。和

dpkg-reconfigure locales

以root用户(多种方式之一)生成/安装更多。

答案 1 :(得分:1)

如果您想在一个特定查询中进行此排序,您可以

ORDER BY regexp_replace(title, '[^a-zA-Z]', '', 'g')

它会从结果字段中删除sting和order中的所有非A-Z