PostgreSQL: запрос, который разбивает массив из одного элемента на несколько элементов на основе разделителя и удаляет его - PullRequest
0 голосов
/ 30 января 2020

Я новичок в PostgreSQl и не могу найти решение, чтобы получить результат, упомянутый ниже.

Я создал таблицу со столбцом типа данных text [], который представляет собой массив текстовых строк (один элемент).

Моя таблица выглядит следующим образом:

col1       col2
ID1      {"P25963(MI:0326), Homo sapiens);O14920(MI:0326), Homo sapiens)"}
ID2      {"Q8NFZ0(MI:0326), Homo sapiens);P12931(MI:0326), Homo sapiens)"}
ID3      {"P26368(MI:0326), Homo sapiens);Q15637(MI:0326), Homo sapiens); Q15638(MI:0326), Homo sapiens)"}

Когда я пытаюсь получить доступ к первому и второму элементу col2, я получаю вывод ниже.

SELECT col2[1] FROM table;

P25963(MI:0326), Homo sapiens);O14920(MI:0326), Homo sapiens
Q8NFZ0(MI:0326), Homo sapiens);P12931(MI:0326), Homo sapiens
P26368(MI:0326), Homo sapiens);Q15637(MI:0326), Homo sapiens); Q15638(MI:0326), Homo sapiens

SELECT col2[2] FROM table;

NULL
NULL
NULL

Я хотел бы разделить этот элемент массива на несколько элементов (наличие;) , развернуть их, а затем выполнить некоторое регулярное выражение для необъявленных строк.

Желаемый вывод после разбиения:

col1       col2
ID1       {P25963(MI:0326), Homo sapiens},{O14920(MI:0326), Homo sapiens}
ID2       {Q8NFZ0(MI:0326), Homo sapiens},{P12931(MI:0326), Homo sapiens}
ID3       {P26368(MI:0326), Homo sapiens},{Q15637(MI:0326), Homo sapiens}, {Q15638(MI:0326), Homo sapiens}

Желаемый результат после удаления:

col1     col3                                 col4   
ID1      P25963(MI:0326), Homo sapiens       O14920(MI:0326), Homo sapiens    
ID2      Q8NFZ0(MI:0326), Homo sapiens       P12931(MI:0326), Homo sapiens  
ID3      P26368(MI:0326), Homo sapiens       Q15637(MI:0326), Homo sapiens
ID3      P26368(MI:0326), Homo sapiens       Q15638(MI:0326), Homo sapiens

Любое предложение будет очень полезным.

Спасибо

1 Ответ

1 голос
/ 30 января 2020

Я бы просто получил доступ к первому элементу в текстовом массиве и использовал бы split_part() для получения основной информации:

select 
    col1,
    split_part(col2[1], ';', 1) col3,
    split_part(col2[1], ';', 2) col4
from mytable

Демонстрация на DB Fiddle :

col1 | col3                           | col4                          
:--- | :----------------------------- | :-----------------------------
ID1  | P25963(MI:0326), Homo sapiens) | O14920(MI:0326), Homo sapiens)
ID2  | Q8NFZ0(MI:0326), Homo sapiens) | P12931(MI:0326), Homo sapiens)
ID3  | P26368(MI:0326), Homo sapiens) | Q15637(MI:0326), Homo sapiens)

Из комментариев: если вы хотите разделить переменное число элементов, я бы рекомендовал разбивать данные на строки, а не на столбцы. Для этого вы можете использовать string_to_array() для разделения строки на массив, затем unnest() для генерации строк:

select
    t.col1,
    s.pos,
    s.val
from mytable t
cross join lateral unnest(string_to_array(t.col2[1], ';')) with ordinality s(val, pos)

Демо :

col1 | pos | val                           
:--- | --: | :-----------------------------
ID1  |   1 | P25963(MI:0326), Homo sapiens)
ID1  |   2 | O14920(MI:0326), Homo sapiens)
ID2  |   1 | Q8NFZ0(MI:0326), Homo sapiens)
ID2  |   2 | P12931(MI:0326), Homo sapiens)
ID3  |   1 | P26368(MI:0326), Homo sapiens)
ID3  |   2 | Q15637(MI:0326), Homo sapiens)
ID3  |   3 | Q15638(MI:0326), Homo sapiens)
...