以声明的方式从Postgres字符串中获取最后一个单词

时间:2022-09-13 14:17:49

[EDIT] original title of this question was "Getting the last element of a Postgres array, declaratively"

[编辑]这个问题的原始标题是“以声明的方式获取Postgres数组的最后一个元素”

How to obtain the last element of the array in Postgres?

如何在Postgres中获取数组的最后一个元素?

I need to do it declaratively as I want to use it as a ORDER BY criteria. I wouldn't want to create a special PGSQL function for it, the less changes to the database the better in this case.

我需要以声明方式进行,因为我想将它用作ORDER BY标准。我不想为它创建一个特殊的PGSQL函数,在这种情况下对数据库的更改越少越好。

In fact, what I want to do is to sort by the last word of a specific column containing multiple words. Changing the model is not an option here.

实际上,我想要做的是按包含多个单词的特定列的最后一个单词进行排序。此处不能更改模型。

In other words, I want to push Ruby's sort_by {|x| x.split[-1]} into the database level. I can split a value into array of words with Postgres string_to_array or regexp_split_to_array functions, then how to get its last element?

换句话说,我想推送Ruby的sort_by {| x | x.split [-1]}进入数据库级别。我可以使用Postgres string_to_array或regexp_split_to_array函数将值拆分为单词数组,然后如何获取其最后一个元素?

8 个解决方案

#1


27  

If I understand your question correctly you have a string and you're first splitting it on some separator and then afterwards finding the last element of the array and discarding the rest.

如果我正确理解你的问题你有一个字符串,你首先将它拆分在某个分隔符上,然后找到数组的最后一个元素并丢弃其余的元素。

You could miss out the middle man and get the last element directly:

你可能会错过中间人并直接得到最后一个元素:

SELECT regexp_replace('foo bar baz', '^.* ', '')

Result:

结果:

baz

#2


12  

Use array_upper():

使用array_upper():

SELECT array_upper(ARRAY[1,2,5,6], 1);

#3


8  

Q: what I want to do is to sort by the last word of a specific column

问:我想要做的是按特定列的最后一个字排序

When dealing with an actual array of text (not a string), use array_upper() in the index.

处理实际的文本数组(不是字符串)时,请在索引中使用array_upper()。

Demo for 1-dimensional array

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)];

Demo for 2-dimensional array

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)];

#4


1  

Edited: THIS IS WRONG -- SEE BELOW FOR CORRECT ANSWER --

编辑:这是错的 - 见下面正确的答案 -

I guess you must use array_length() :

我想你必须使用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

To use this declaratively, (on the fly) you can create a little SQL function:

要以声明方式使用它,(在运行中)您可以创建一个小的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

------- EDITED -- CORRECT ANSWER FOLLOWS ----------------------

-------编辑 - 正确回答----------------------

The above is not correct because in Postgresql arrays can sometimes be not one-based.

以上是不正确的,因为Postgresql数组有时可能不是基于一个。

The correct way, then, is with array_upper()

然后,正确的方法是使用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

#5


1  

You can do the following:

您可以执行以下操作:

SELECT (ARRAY[1,8,3,7])[array_upper(ARRAY[1,8,3,7], 1)];

SELECT(ARRAY [1,8,3,7])[array_upper(ARRAY [1,8,3,7],1)];

I.e. get the index and then select that last element.

即获取索引,然后选择最后一个元素。

#6


1  

UPDATE: the question was edited, so I update my answer.

更新:问题已编辑,所以我更新了我的答案。

You can also use array_upper() to return the element itself (not just its index):

您还可以使用array_upper()返回元素本身(而不仅仅是其索引):

SELECT arr[array_upper(arr, 1)] FROM (SELECT ARRAY[1,2,3,6] AS arr) AS t

So the anwer is:

所以anwer是:

SELECT arr[array_upper(arr, 1)] FROM (SELECT string_to_array('one two three', ' ') AS arr) AS t

result: 'three'

结果:'三'

#7


0  

You can combine string_to_array and array_length

您可以组合string_to_array和array_length

select 
(string_to_array(column_name, '.'))[array_length((string_to_array(column_name, '.')), 1)]
from table_name;

This will split the string in column_name into array using "." as delimiter and will give you the last part

这将使用“。”将column_name中的字符串拆分为数组。作为分隔符,将给你最后一部分

#8


0  

This is a more generic answer to 'how to get the last element of an array'.

这是“如何获取数组的最后一个元素”的更通用的答案。

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)

array_upper

Returns the index of the last element of an array. So to use it, you have to reference the array twice: some_array[array_upper(some_array, 1)]

返回数组的最后一个元素的索引。所以要使用它,你必须引用两次数组:some_array [array_upper(some_array,1)]


So if you already have your array:

所以,如果你已经有你的阵列:

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)

It's less verbose to select the last element:

选择最后一个元素并不那么冗长:

trader=# select name_parts[array_upper(name_parts, 1)] from temp2;
 name_parts 
------------
 baz
(1 row)

#1


27  

If I understand your question correctly you have a string and you're first splitting it on some separator and then afterwards finding the last element of the array and discarding the rest.

如果我正确理解你的问题你有一个字符串,你首先将它拆分在某个分隔符上,然后找到数组的最后一个元素并丢弃其余的元素。

You could miss out the middle man and get the last element directly:

你可能会错过中间人并直接得到最后一个元素:

SELECT regexp_replace('foo bar baz', '^.* ', '')

Result:

结果:

baz

#2


12  

Use array_upper():

使用array_upper():

SELECT array_upper(ARRAY[1,2,5,6], 1);

#3


8  

Q: what I want to do is to sort by the last word of a specific column

问:我想要做的是按特定列的最后一个字排序

When dealing with an actual array of text (not a string), use array_upper() in the index.

处理实际的文本数组(不是字符串)时,请在索引中使用array_upper()。

Demo for 1-dimensional array

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)];

Demo for 2-dimensional array

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)];

#4


1  

Edited: THIS IS WRONG -- SEE BELOW FOR CORRECT ANSWER --

编辑:这是错的 - 见下面正确的答案 -

I guess you must use array_length() :

我想你必须使用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

To use this declaratively, (on the fly) you can create a little SQL function:

要以声明方式使用它,(在运行中)您可以创建一个小的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

------- EDITED -- CORRECT ANSWER FOLLOWS ----------------------

-------编辑 - 正确回答----------------------

The above is not correct because in Postgresql arrays can sometimes be not one-based.

以上是不正确的,因为Postgresql数组有时可能不是基于一个。

The correct way, then, is with array_upper()

然后,正确的方法是使用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

#5


1  

You can do the following:

您可以执行以下操作:

SELECT (ARRAY[1,8,3,7])[array_upper(ARRAY[1,8,3,7], 1)];

SELECT(ARRAY [1,8,3,7])[array_upper(ARRAY [1,8,3,7],1)];

I.e. get the index and then select that last element.

即获取索引,然后选择最后一个元素。

#6


1  

UPDATE: the question was edited, so I update my answer.

更新:问题已编辑,所以我更新了我的答案。

You can also use array_upper() to return the element itself (not just its index):

您还可以使用array_upper()返回元素本身(而不仅仅是其索引):

SELECT arr[array_upper(arr, 1)] FROM (SELECT ARRAY[1,2,3,6] AS arr) AS t

So the anwer is:

所以anwer是:

SELECT arr[array_upper(arr, 1)] FROM (SELECT string_to_array('one two three', ' ') AS arr) AS t

result: 'three'

结果:'三'

#7


0  

You can combine string_to_array and array_length

您可以组合string_to_array和array_length

select 
(string_to_array(column_name, '.'))[array_length((string_to_array(column_name, '.')), 1)]
from table_name;

This will split the string in column_name into array using "." as delimiter and will give you the last part

这将使用“。”将column_name中的字符串拆分为数组。作为分隔符,将给你最后一部分

#8


0  

This is a more generic answer to 'how to get the last element of an array'.

这是“如何获取数组的最后一个元素”的更通用的答案。

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)

array_upper

Returns the index of the last element of an array. So to use it, you have to reference the array twice: some_array[array_upper(some_array, 1)]

返回数组的最后一个元素的索引。所以要使用它,你必须引用两次数组:some_array [array_upper(some_array,1)]


So if you already have your array:

所以,如果你已经有你的阵列:

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)

It's less verbose to select the last element:

选择最后一个元素并不那么冗长:

trader=# select name_parts[array_upper(name_parts, 1)] from temp2;
 name_parts 
------------
 baz
(1 row)