Getting the last word from a Postgres string, declaratively

前端 未结 8 2372
无人及你
无人及你 2021-02-07 00:18

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

How to obtain the last element of the array in Postgr

相关标签:
8条回答
  • 2021-02-07 00:24

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


    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)
    
    0 讨论(0)
  • 2021-02-07 00:27

    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.

    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)];
    
    0 讨论(0)
  • 2021-02-07 00:34

    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
    
    0 讨论(0)
  • 2021-02-07 00:38

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

    I guess you must use 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:

    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.

    The correct way, then, is with 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
    
    0 讨论(0)
  • 2021-02-07 00:40

    You can combine string_to_array and 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

    0 讨论(0)
  • 2021-02-07 00:44

    Use array_upper():

    SELECT array_upper(ARRAY[1,2,5,6], 1);
    
    0 讨论(0)
提交回复
热议问题