是否可以通过包含诸如[](),;
etc 之类的字符的标题字段对 PostgreSQL 查询的结果进行排序,但这样做会忽略这些标点符号并仅按文本字符排序?
我已阅读有关更改数据库排序规则或语言环境的文章,但没有找到任何关于如何在现有数据库上按列执行此操作的明确说明。这甚至可能吗?
是否可以通过包含诸如[](),;
etc 之类的字符的标题字段对 PostgreSQL 查询的结果进行排序,但这样做会忽略这些标点符号并仅按文本字符排序?
我已阅读有关更改数据库排序规则或语言环境的文章,但没有找到任何关于如何在现有数据库上按列执行此操作的明确说明。这甚至可能吗?
您可以使用子句中regexp_replace()
的模式'[^a-zA-Z]'
,ORDER BY
但它只识别纯 ASCII 字母。更好地使用类速记'\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
->用于 Postgres 9.2 的 SQLfiddle。
->用于 Postgres 9.1 的 SQLfiddle。
正则表达式代码已在 9.2 版本中更新。我假设这是 9.2 中改进处理的原因,其中示例中的所有字母字符都匹配,而 9.1 只匹配一些。
unaccent()
由附加模块unaccent提供。跑:
CREATE EXTENSION unaccent;
每个数据库使用一次(Postgres 9.1+,旧版本使用不同的技术)。
您必须知道 Postgres 依赖于底层操作系统的语言环境(包括排序规则)。排序顺序受您选择的区域设置或更具体的控制LC_COLLATE
。更多相关答案:
字符串排序顺序(LC_COLLATE 和 LC_CTYPE)
有计划将排序规则支持直接合并到 Postgres中,但目前不可用。
许多语言环境忽略了您描述的用于对字符数据进行开箱即用排序的特殊字符。如果您的系统中安装了提供您正在查找的排序顺序的语言环境,您可以在 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 用户(几种方式之一)生成/安装更多。
如果您想在一个特定查询中进行此排序,您可以
ORDER BY regexp_replace(title, '[^a-zA-Z]', '', 'g')
它将A-Z
按结果字段从 sting 和 order 中删除所有非。