I have such an example of tables:
table1:
col 1 | col2 | col3 | col4 |
---|---|---|---|
1 | a | x1 | asdc |
2 | b | x2 | czxa |
3 | c | x3 | xfsdaa |
table2:
col2 | col3 |
---|---|
l | x56 |
q | x99 |
All I want is to receive such a final concatenation
col 1 | col2 | col3 | col4 |
---|---|---|---|
1 | a | x1 | asdc |
2 | b | x2 | czxa |
3 | c | x3 | xfsdaa |
null | l | x56 | null |
null | q | x99 | null |
How can I make it in RSQL (postgresql based SQL)? I thought about selecting all columns from the first table, then union all
and use NULL AS col1 [...] NULL AS col4
in the place of missing columns, but in real data I have dozens of columns so the code won’t look great with it.
Is there some other way to achieve it?
2
Answers
If you don’t mind reordered columns you can get away with a
natural full outer join
:Which means it’ll deduplicate columns with matching names, without you having to name them or even know them. Demo at db<>fiddle:
Problem is, matching values in columns with matching names will be joined together. It might as well be the desired effect but if it’s not, you can force the mismatch using the fact that joining on
null
values results in a mismatch:I’ve added
tableoid
system column only to show(c, x3)
was in both tables. It potentially offers some added utility and you can force the mismatch using just that, but otherwise it’s enough to add a constantlynull
column with the same name on both sides.Keep in mind that
natural join
is a sensitive topic: it’s risky and typically advised against.That being said, what you proposed with the
UNION
clause andnull
constants wherever you want to skip a field is the most obvious, but it should also perform better: demoIf you don’t like Union and have multiple tables then you can use
full outer join
db-fiddle
Query