I have two tables (simplified).
table1:
- id (serial)
table2:
- table1_id (integer)
- value (text)
- type (integer)
I want to join these two tables, but depending on the type, I want to join the "value" of table2 into different columns. Result should look like this:
id | table2value0 | table2value1 | table2othervalues
table2value0
is the value from table2
where type
is 0.
table2value1
is the value from table2
where type
is 1.
table2othervalues
are the remaining values where type
is something else, as an array.
If there are more than one value for table2value0
and table2value1
, I only want the first. Order doesn't matter, so the order it was inserted.
If some entries in table1 do not have matches in table2, they should appear in the output as NULL.
Best Answer
Assuming Postgres 9.4 or later:
The aggregate
FILTER
clause was introduced with pg 9.4. There are various less elegant alternatives for older versions:This returns one row for every row in
table1
, missing types intable2
result in NULL values.You seem to be under the impression that there is a natural order of rows, but there is not:
I picked the minimum
value
instead, since your requirement is effectively undefined.The best query depends on your actual table definition (including all constraints).
In particular, the expression
type IN (1,2) IS NOT TRUE
also catchestype IS NULL
, which may not be necessary, depending on your missing table definition.Related:
Aside:
Your desire to return a single (scalar) value for types 1 and 2, but an array for the rest makes it harder to solve with
crosstab()
(but still possible). Basics: