[EDIT]这个问题的原始标题是“以声明的方式获取Postgres数组的最后一个元素”
如何在Postgres中获取数组的最后一个元素?
我需要以声明方式进行,因为我想将其用作ORDER BY标准。我不想为它创建一个特殊的PGSQL函数,在这种情况下对数据库的更改越少越好。
实际上,我想要做的是按包含多个单词的特定列的最后一个单词进行排序。此处不能更改模型。
换句话说,我想将Ruby的sort_by {|x| x.split[-1]}
推入数据库级别。我可以使用Postgres string_to_array
或regexp_split_to_array
函数将值拆分为单词数组,然后如何获取其最后一个元素?
答案 0 :(得分:31)
如果我正确理解你的问题你有一个字符串,你首先将它拆分在某个分隔符上,然后找到数组的最后一个元素并丢弃其余元素。
你可能会错过中间人并直接获得最后一个元素:
SELECT regexp_replace('foo bar baz', '^.* ', '')
结果:
baz
答案 1 :(得分:13)
SELECT array_upper(ARRAY[1,2,5,6], 1);
答案 2 :(得分:9)
问:我想要做的是按特定列的最后一个字排序
在处理text
的实际数组(不是字符串)时,请在索引中使用array_upper()
。
WITH x(a) AS (
VALUES
('{zoo, zar, zaz}'::text[])
,('{3,4,5,6}')
,('{foo, bar, baz}')
)
SELECT *
FROM x
ORDER BY a[array_upper(a, 1)];
WITH x(a) AS (
VALUES
('{{zoo, zar, zaz}
,{4,5,6}
,{14,15,16}
,{foo, bar, zzzaz}}'::text[])
,('{{zoo, zar, baz}
,{4,5,6}
,{14,15,16}
,{foo, bar, aaaaz}}'::text[])
)
SELECT *
FROM x
ORDER BY a[array_upper(a, 1)][array_upper(a, 2)];
答案 3 :(得分:3)
您可以执行以下操作:
SELECT (ARRAY[1,8,3,7])[array_upper(ARRAY[1,8,3,7], 1)];
即。获取索引,然后选择最后一个元素。
答案 4 :(得分:3)
从 Postgres 字符串中获取最后一个单词:
在 postgresql 14 中你可以这样做:
SELECT split_part('this is my word', ' ', -1);
从示例中的 word
字符串中获取最后一个单词
这是 psql14 的新功能,因为现在 split_part
接受负索引
详情见changelog
答案 5 :(得分:1)
编辑:这是错的 - 见下面正确的答案 -
我猜您必须使用array_length()
:
SELECT string_to_array('hi guys, welcome', ' ') AS arr INTO temparr;
SELECT * FROM temparr;
arr
----------------------
{hi,"guys,",welcome}
SELECT arr[array_length(arr,1)] FROM temparr;
arr
---------
welcome
要以声明方式使用它,(在运行中)您可以创建一个小的SQL函数:
CREATE FUNCTION last_elem (text[]) RETURNS text AS $$
SELECT $1[array_length($1,1)];
$$ LANGUAGE SQL;
select last_elem(string_to_array('hi guys, welcome', ' '));
last_elem
-----------
welcome
-------编辑 - 正确回答----------------------
以上是不正确的,因为Postgresql数组有时可能不是基于一个。
然后,正确的方法是使用array_upper()
CREATE FUNCTION last_elem (text[]) RETURNS text AS $$
SELECT $1[array_upper($1,1)];
$$ LANGUAGE SQL;
select last_elem(string_to_array('hi guys, welcome', ' '));
last_elem
-----------
welcome
答案 6 :(得分:1)
更新:问题已编辑,所以我更新了答案。
您还可以使用array_upper()返回元素本身(而不仅仅是其索引):
SELECT arr[array_upper(arr, 1)] FROM (SELECT ARRAY[1,2,3,6] AS arr) AS t
所以anwer是:
SELECT arr[array_upper(arr, 1)] FROM (SELECT string_to_array('one two three', ' ') AS arr) AS t
结果:'three'
答案 7 :(得分:0)
您可以组合string_to_array和array_length
select
(string_to_array(column_name, '.'))[array_length((string_to_array(column_name, '.')), 1)]
from table_name;
这将使用“。”将column_name中的字符串拆分为数组。作为分隔符,并将给你最后一部分
答案 8 :(得分:0)
这是如何获取数组的最后一个元素的更通用的答案。
trader=# create table temp (name varchar);
CREATE TABLE
trader=# insert into temp (name) values ('foo bar baz');
INSERT 0 1
trader=# select (regexp_split_to_array(name, ' ')) from temp;
regexp_split_to_array
-----------------------
{foo,bar,baz}
(1 row)
trader=# select (regexp_split_to_array(name, ' '))[array_upper(regexp_split_to_array(name, ' '), 1)] from temp;
regexp_split_to_array
-----------------------
baz
(1 row)
返回数组最后一个元素的索引。因此,要使用它,您必须引用数组两次:some_array[array_upper(some_array, 1)]
所以如果你已经有了你的阵列:
trader=# create view temp2 as (select regexp_split_to_array(name, ' ') as name_parts from temp);
CREATE VIEW
trader=# select * from temp2;
name_parts
---------------
{foo,bar,baz}
(1 row)
选择最后一个元素并不那么冗长:
trader=# select name_parts[array_upper(name_parts, 1)] from temp2;
name_parts
------------
baz
(1 row)