Reputation: 1286
Let's say I have three tables in a PostgreSQL database.
A films
table
+-------------+----------+
| film | theme_id |
+-------------+----------+
| film name 1 | 23 |
| film name 2 | 56 |
| film name 3 | 11 |
| film name 4 | 12 |
+-------------+----------+
a themes_old
table
+----------+------------+
| theme_id | streams_on |
+----------+------------+
| 23 | Spotify |
| 56 | Tidal |
+----------+------------+
and a themes_new
table
+----------+------------+
| theme_id | streams_on |
+----------+------------+
| 11 | Spotify |
| 56 | Tidal |
+----------+------------+
I want to join both the second and third tables to the first but without the repeated streams_on column. E.g. if I run
SELECT *
FROM films as f
LEFT JOIN themes_old as to ON f.theme_id=to.theme_id
LEFT JOIN themes_new as tn on f.theme_id=tn.theme_id
I would get
+-------------+----------+------------+------------+
| film | theme_id | streams_on | streams_on |
+-------------+----------+------------+------------+
| film name 1 | 23 | Spotify | [null] |
| film name 2 | 56 | Tidal | Tidal |
| film name 3 | 11 | [null] | Spotify |
| film name 4 | 12 | [null] | [null] |
+-------------+----------+------------+------------+
But I want to merge the last two columns so that there is just one streams_on column such that for any row if one streams_on column value is null, take the other one, if both are not null take perhaps the first one and if both are null then default to null. This should give a table like this:
+-------------+----------+------------+
| film | theme_id | streams_on |
+-------------+----------+------------+
| film name 1 | 23 | Spotify |
| film name 2 | 56 | Tidal |
| film name 3 | 11 | Spotify |
| film name 4 | 12 | [null] |
+-------------+----------+------------+
I feel like this is a job for self join or something but I can't find much by searching. Any ideas? By the way both streams_on columns should be considered enums.
Upvotes: 0
Views: 52
Reputation: 31
This can be done using isnull function. I used SQLserver for this solution. It checks the theme available in the new table if not it uses the old theme. Let me know if this helps you.
select f.film_name,
isnull(new.theme_id,old.theme_id),
isnull(new.streams_on, old.streams_on)
from films f
left join themes_old old
on f.theme_id = old.theme_id
left join themes_new new
on f.theme_id = new.theme_id
Upvotes: 0
Reputation: 11
I'd suggest using a Case Statement if only because you can add in a value to appear in place of the null value. It makes it easier to quickly export the information to reports
SELECT
theme_id,
CASE
WHEN themes_new.streams_on IS NOT NULL THEN themes_new.streams_on
WHEN (themes_new.streams_on IS NULL AND themes_old.streams_on IS NULL) THEN "None"
ELSE themes_old.streams_on
FROM films as f
LEFT JOIN themes_old as to on f.theme_id=to.theme_id
LEFT JOIN themes_new as tn on f.theme_id=tn.theme_id
Upvotes: 0
Reputation: 147196
You can use COALESCE
to merge the two column values:
SELECT f.film, f.theme_id, COALESCE(to.streams_on, tn.streams_on) AS streams_on
FROM films as f
LEFT JOIN themes_old as to on f.theme_id=to.theme_id
LEFT JOIN themes_new as tn on f.theme_id=tn.theme_id
If you want to prioritise the "new" streams over the "old", just change the order of the values in the COALESCE
i.e.
COALESCE(tn.streams_on, to.streams_on) AS streams_on
Upvotes: 2