Sql 支持大数的自然排序
我有一些数据如下:Sql 支持大数的自然排序,sql,postgresql,natural-sort,Sql,Postgresql,Natural Sort,我有一些数据如下: id | templateName ----+-------------- 10 | a 61 | a 63 | a 4 | a 6 | a 7 | a 34 | a 35 | a 62 | a 1 | a 13 | a 25 | a 26 | a 66 | a 68 | a 70 | a 65 | a 5 | a1 73 | a5 3 | a15 2 | a15a 69 | a15b 64 | a15b4 7
id | templateName
----+--------------
10 | a
61 | a
63 | a
4 | a
6 | a
7 | a
34 | a
35 | a
62 | a
1 | a
13 | a
25 | a
26 | a
66 | a
68 | a
70 | a
65 | a
5 | a1
73 | a5
3 | a15
2 | a15a
69 | a15b
64 | a15b4
74 | a15b21
8 | a214748364
... ORDER BY "templateName" COLLATE natural
我正在使用以下代码进行自然排序:
CREATE TYPE ai AS (a text, i int);
select id, "templateName" from daily_templates
order by ARRAY(SELECT ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai
FROM regexp_matches("templateName", '(\D*)(\d*)', 'g') x)
, "templateName";
它工作得很好,就像我上面展示的。现在我想支持大量的数据,比如
a111111111111111111111
这将超出整数的范围。我该怎么做?
参考资料:它的工作原理与@clemens建议的类似。在复合类型中使用数值
(=十进制
):
CREATE TYPE ai AS (a text, i numeric);
小提琴
我在参考答案中使用int
的原因是性能。或者,如果您有支持ICU排序的PostgreSQL v10或更高版本,您可以
CREATE COLLATION natural (provider = icu, locale = 'en-US-u-kn-true');
然后像这样排序:
id | templateName
----+--------------
10 | a
61 | a
63 | a
4 | a
6 | a
7 | a
34 | a
35 | a
62 | a
1 | a
13 | a
25 | a
26 | a
66 | a
68 | a
70 | a
65 | a
5 | a1
73 | a5
3 | a15
2 | a15a
69 | a15b
64 | a15b4
74 | a15b21
8 | a214748364
... ORDER BY "templateName" COLLATE natural
如果您的数字不是任意大的,您可以在ai
中对i
使用BIGINT
(=8字节整数)而不是INT
。对于非常大的数字,DECIMAL
可能是一个解决方案。我试图创建I bigint,但它仍然转换为整数,我认为由于regexp\u matchesHi,我跳入了一个问题,它与排序的性能有关。有什么办法可以改进吗?这可能是没有办法的。排序越复杂,排序成本就越高。