PostgreSQL 可以使用 array subscripts starting anywhere .
考虑这个示例,它创建一个包含 3 个元素的数组,下标从 5 到 7:
SELECT '[5:7]={1,2,3}'::int[];
返回:
[5:7]={1,2,3}
我们在下标 5
处获取第一个元素:
SELECT ('[5:7]={1,2,3}'::int[])[5];
我想规范化一维数组以从数组下标 1 开始。
我能想到的最好的:
SELECT ('[5:7]={1,2,3}'::int[])[array_lower('[5:7]={1,2,3}'::int[], 1):array_upper('[5:7]={1,2,3}'::int[], 1)]
相同,更容易阅读:
WITH cte(a) AS (SELECT '[5:7]={1,2,3}'::int[])
SELECT a[array_lower(a, 1):array_upper(a, 1)]
FROM cte;
您知道更简单/更快或至少更优雅的方法吗?
在 Postgres 9.5 上使用旧解决方案进行基准测试
db<> fiddle here
基准测试包括 Postgres 14 上的新解决方案
db<> fiddle here
最佳答案
最终,something more elegant popped up使用 Postgres 9.6。 The manual:
It is possible to omit the
lower-bound
and/orupper-bound
of a slice specifier; the missing bound is replaced by the lower or upper limit of the array's subscripts. For example:
所以现在很简单:
SELECT my_arr<b>[:]</b>;
对于我的示例数组文字,您需要用括号括起来以使语法明确:
SELECT <b>(</b>'[5:7]={1,2,3}'::int[]<b>)[:]</b>;
性能与 Daniel's solution with hard-coded max array subscripts 大致相同- 这仍然是 Postgres 9.5 或更早版本的方式。
关于sql - 标准化数组下标,使它们从 1 开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12011569/