Mit*_*ran 14 sql postgresql types natural-sort sql-order-by
我ORDER BY在下表中遇到了Postgres 问题:
em_code name
EM001 AAA
EM999 BBB
EM1000 CCC
Run Code Online (Sandbox Code Playgroud)
要向表中插入新记录,
SELECT * FROM employees ORDER BY em_code DESCec_alphaec_numec_num++ec_alpha再次当em_code到达EM1000,上述算法失败.
第一步将返回EM999而不是EM1000,它将再次生成EM1000为新的em_code,打破了唯一键约束.
知道如何选择EM1000吗?
Bou*_*egh 31
从 Postgres 9.6 开始,可以指定一个排序规则来自然地对带有数字的列进行排序。
\nhttps://www.postgresql.org/docs/10/collation.html
\n-- First create a collation with numeric sorting\nCREATE COLLATION numeric (provider = icu, locale = \'en@colNumeric=yes\');\n\n-- Alter table to use the collation\nALTER TABLE "employees" ALTER COLUMN "em_code" type TEXT COLLATE numeric;\nRun Code Online (Sandbox Code Playgroud)\n现在只需像其他方式一样查询即可。
\nSELECT * FROM employees ORDER BY em_code
在我的数据上,我按以下顺序得到结果(请注意,它还会对外来数字进行排序):
\n| 价值 |
|---|
| 0 |
| 0001 |
| 001 |
| 1 |
| 06 |
| 6 |
| 13 |
| \xdb\xb1\xdb\xb3 |
| 14 |
原因是字符串按字母顺序排序(而不是像你想要的那样数字排序)和1之前的排序.你可以像这样解决它:
SELECT * FROM employees ORDER BY substring(em_code, 3)::int DESC
Run Code Online (Sandbox Code Playgroud)
em_code如果可以的话,从你的中删除多余的"EM"会更有效- 并保存一个整数开头.
要从字符串中删除任何和所有非数字:
SELECT regexp_replace(em_code, E'\\D','','g')
FROM employees
Run Code Online (Sandbox Code Playgroud)
\D是"非数字" 的正则表达式类 - 简写.
'g'第四个参数是"全局"开关,用于将替换应用于字符串中的每个匹配项,而不仅仅是第一个.
所以我用空字符串替换每个非数字,只从字符串中提取数字.
您可以采用的一种方法是为此创建一个naturalsort函数。这是一个由Postgres传奇人物RhodiumToad编写的示例。
create or replace function naturalsort(text)
returns bytea language sql immutable strict as $f$
select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), 'SQL_ASCII'),'\x00')
from regexp_matches($1, '0*([0-9]+)|([^0-9]+)', 'g') r;
$f$;
Run Code Online (Sandbox Code Playgroud)
资料来源:http : //www.rhodiumtoad.org.uk/junk/naturalsort.sql
要使用它,只需按以下顺序调用函数:
SELECT * FROM employees ORDER BY naturalsort(em_code) DESC
Run Code Online (Sandbox Code Playgroud)
这总是在问题和我自己的发展中出现,我终于厌倦了棘手的方法。我终于分解并实现为PostgreSQL扩展:
https://github.com/Bjond/pg_natural_sort_order
MIT许可证免费使用。
基本上,它只是规范化字符串中的数字(零个前置数字),以便您可以为全速排序自然创建索引列。自述文件进行了解释。
好处是您可以让触发器来完成工作,而不是应用程序代码。它将在PostgreSQL服务器上以机器速度进行计算,并且添加列的迁移变得简单而快速。