We have localized system that stores movies in multiple languages. Below is the table structure.
CREATE TABLE movies (
id SERIAL PRIMARY KEY,
title TEXT,
year_of_release smallint
);
CREATE TABLE movies_localized (
movie_id INT,
locale VARCHAR(8) NOT NULL,
title TEXT,
FOREIGN KEY (movie_id) REFERENCES movies (id),
PRIMARY KEY(movie_id, locale)
);
Please note that for a movie title
can be in multiple languages here as year_of_release
can not be localized. Lets create the data now
-- Movie which has title for both en and ta
INSERT INTO movies(title, year_of_release)
VALUES ('Avatar', 2009);
INSERT INTO movies_localized(movie_id, locale, title)
VALUES (currval('movies_id_seq'), 'ta', 'அவதார்');
INSERT INTO movies_localized(movie_id, locale, title)
VALUES (currval('movies_id_seq'), 'tl', 'అవతార్');
-- Movie which has title only for ta
INSERT INTO movies(title, year_of_release)
VALUES ('Inception', 2010);
-- Movie which has no title at all
INSERT INTO movies(title, year_of_release)
VALUES (NULL, 2000);
Now we need to consider 3 scnerios when we read movie data for specific language for e.g ta
- For the movie
Avatar
it should returnஅவதார்
- For the movie
Inception
it should returnInception
as fallback since there is no localized value - For the third it should return NULL
Lets get all the movies
SELECT id, title, year_of_release FROM movies
Lets join the movie_localized
SELECT id,
m.title, ml.title,
year_of_release
FROM movies m
LEFT JOIN movies_localized ml ON m.ID = ml.movie_id
Time to solve our actual problem of fall back locale. here is where CASE comes to help us
SELECT id,
CASE
WHEN ml.title IS NULL
THEN m.title
ELSE ml.title
END AS title,
year_of_release
FROM movies m
LEFT JOIN movies_localized ml
ON m.id = ml.movie_id
WHERE ml.locale IS NULL
OR ml.locale = 'ta'
Cool isn’t it ? But wait . Is there any better way to it ?!
SELECT id,
COALESCE(ml.title, m.title) AS title,
year_of_release
FROM movies m
LEFT JOIN movies_localized ml
ON m.id = ml.movie_id
WHERE ml.locale IS NULL
OR ml.locale = 'ta'
Which is better. You can EXPLAIN yourself 😊