28

Given a table defined as such:

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

...and the following values:

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

I'm trying to find a query which will return:

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

I've reviewed the upstream documentation on accessing arrays, and tried to think about what a solution using the unnest() function would look like, but have been coming up empty.

An ideal solution would be easy to use even in cases where there were a significant number of columns other than the array being expanded and no primary key. Handling a case with more than one array is not important.

1
  • 3
    Doesn't select name, unnest(values) "value" from test_values; work? Commented Aug 13, 2015 at 20:22

2 Answers 2

33

We can put the set-returning function unnest() into the SELECT list like Raphaël suggests. This used to exhibit corner case problems before Postgres 10. See:

Since Postgres 9.3 we can also use a LATERAL join for this. It is the cleaner, standard-compliant way to put set-returning functions into the FROM list, not into the SELECT list:

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

One subtle difference: this drops rows with empty / NULL values from the result since unnest() returns no row, while the same is converted to a NULL value in the FROM list and returned anyway. The 100 % equivalent query is:

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

See:

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the nice answer. A quick question. What is the v(value) on the last query. I understood that v is the alias, but I have never seen this notation in the past. Many thanks again for your answer
14

Well, you give the data, the doc, so... let's mix it ;)

select 
 name, 
 unnest(values) as value 
from test_values

see SqlFiddle

1 Comment

Unfamiliar with the semantics of selecting a tuple with a sequence as one of its elements, I can plead. I'll accept this when the timer runs out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.