2009-12-31 2 views
16

Я ищу функцию типа regexp_split_to_table, но наш db - это версия 8.2.9, поэтому она не имеет ее. Я действительно только расщепление на пространстве, поэтому строка какsql split string by space in table в postgresql

how now brown cow

вернется

+------+ 
|Column| 
+------+ 
|how | 
|now | 
|brown | 
|cow | 
+------+ 

есть простая функция, которая может справиться с этим, или что-то я должен написать сам?

ответ

34

Вы можете разбить массив на набор результатов с помощью функции unsest, и вы можете преобразовать строковый литерал в массив с помощью функции string_to_array. Комбинат как и вы получите это:

alvherre=# select unnest(string_to_array('the quick lazy fox', ' ')); 
unnest 
-------- 
the 
quick 
lazy 
fox 
(4 filas) 

С 8.2 не UNNEST, вы можете записать его в PostgreSQL, как это:

create or replace function unnest(anyarray) returns setof anyelement 
language sql as $$ 
    select $1[i] from generate_series(array_lower($1, 1), 
            array_upper($1, 1)) as i; 
$$; 
+0

+1 для * generate_series * и * unsest *. – pilcrow

2

Я думаю, вам нужно будет RETURNS SET или RETURNS TABLE самостоятельно.

Обновленный ответ: с помощью PL/PgSQL:

pg=> CREATE OR REPLACE FUNCTION string_to_rows(text) RETURNS SETOF TEXT AS $$ 
    DECLARE 
    elems text[];  
    BEGIN 
    elems := string_to_array($1, ' '); 
    FOR i IN array_lower(elems, 1) .. array_upper(elems, 1) LOOP 
     RETURN NEXT elems[i]; 
    END LOOP; 
    RETURN; 
    END 
$$ LANGUAGE 'plpgsql'; 
CREATE FUNCTION 

pg=> SELECT "Column" FROM string_to_rows('how now brown cow') d("Column"); 
Column 
-------- 
how 
now 
brown 
cow 
(4 rows) 

Оригинальный ответ: с помощью PL/Perl:

pg=> CREATE LANGUAGE plperl; 
CREATE LANGUAGE 

pg=> CREATE FUNCTION psplit_to_rows(text) RETURNS SETOF TEXT AS $$ 
pg$> for my $t (split ' ', $_[0]) { return_next $t; } 
pg$> undef; 
pg$> $$ LANGUAGE plperl; 
CREATE FUNCTION 

pg=> SELECT "Column" FROM psplit_to_rows('how now brown cow') d("Column"); 
Column 
-------- 
how 
now 
brown 
cow 
(4 rows) 

Очевидно, что вы можете расширить это, чтобы справиться с разделителем по вашему выбору и т. д. (Заметьте, я не уверен, действительно ли вам нужен столбец с именем «Столбец», требующий котировки идентификатора, чтобы избежать столкновения с ключевым словом, но там вы.)

+0

Я не plperl для работы, это может быть легко сделано w/plpgsql? – veilig

+0

@veilig, да, обновлено. – pilcrow

+0

@pilcrow, ваша функция отлично работает, но у меня возникла проблема, когда я пытаюсь выполнить запрос, например [select string_to_rows (column) из таблицы]. Продолжает выдавать мне ошибку: ОШИБКА: функция set-value, вызываемая в контексте, которая не может принять набор. Оглядываясь в сети, я вижу, мне нужно вызвать, как [select * from string_to_rows (text)]. Можно ли вызвать эту функцию и передать ее в комплекте? ie [выберите * from string_to_rows (выберите col from table)]. – veilig