PostgreSQL: выравнивание отношения с массивом для выдачи одной строки на запись массива

Учитывая таблицу, определенную как таковую:

CREATE TABLE test_values(name TEXT, values INTEGER[]);

... и следующие значения:

| name  | values  |
+-------+---------+
| hello | {1,2,3} |
| world | {4,5,6} |

Я пытаюсь найти запрос, который вернет:

| name  | value |
+-------+-------+
| hello | 1     |
| hello | 2     |
| hello | 3     |
| world | 4     |
| world | 5     |
| world | 6     |

Я рассмотрел исходную документацию по доступу к массивам и попытался подумать о том, что решение, использующее unnest() Функция выглядела бы как, но была пустой.

Идеальное решение было бы простым в использовании даже в тех случаях, когда существенное количество столбцов отличалось от расширяемого массива и не было первичного ключа. Обработка случая с несколькими массивами не важна.

2 ответа

Решение

Вы можете поставить функцию возврата набора unnest() в SELECT список, как предлагает Рафаэль. Но в Postgres 9.3 или новее используйте LATERAL присоединяйтесь к этому вместо этого. Это более чистый, предпочтительный, совместимый со стандартами способ помещения функций, возвращающих множество, в FROM список, а не в SELECT список:

SELECT name, value
FROM   tbl, unnest(values) value;  -- implicit CROSS JOIN LATERAL

Одно тонкое отличие: это отбрасывает строки с пустым / NULL values из результата с unnest() не возвращает строки, в то время как то же самое преобразуется в значение NULL в FROM список и все равно вернулся. 100 % эквивалентный запрос:

SELECT t.name, v.value
FROM   tbl t
LEFT   JOIN unnest(t.values) v(value) ON true;

Ну, вы даете данные, документ, так что... давайте смешаем это;)

select 
 name, 
 unnest(values) as value 
from test_values

см. SqlFiddle

Другие вопросы по тегам