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