Reputation: 4109
I'd like to select translations for products by a given language, but also include a fallback when the translation is not present. This is the dataset:
+----+------------+---------------+-----------------+
| id | product_id | language_code | name |
+----+------------+---------------+-----------------+
| 1 | 1 | en | Name in english |
| 2 | 1 | fr | Name in french |
| 3 | 1 | es | Name in spanish |
| 4 | 2 | en | Another product |
+----+------------+---------------+-----------------+
I'm working on a query which selects language_code='fr' and fallback to 'en' if 'fr' is not present. The result should be something along the lines of:
+----+------------+---------------+-----------------+
| id | product_id | language_code | name |
+----+------------+---------------+-----------------+
| 2 | 1 | fr | Name in french |
| 4 | 2 | en | Another product |
+----+------------+---------------+-----------------+
I've tried multiple things:
SELECT translations.id, translations.language_code, translations.name
FROM translations
WHERE language_code = 'fr'
OR language_code = 'en';
This will limit to the given languages, but does not remove duplicates (id=1).
I've seen multiple solutions with GROUP BY
, but I keep running in only_full_group_by
issues, which I don't know how to fix.
SELECT *
FROM translations
WHERE language_code = 'fr'
OR language_code = 'en'
GROUP BY product_id;
Upvotes: 2
Views: 93
Reputation: 1606
If English names available for all products you can try to use LEFT JOIN:
SELECT
e.product_id
, IF(f.name IS NOT NULL, f.name, e.name) AS name
FROM
translations AS e
LEFT JOIN translations AS f ON (
f.product_id = e.product_id
AND f.language_code = 'fr'
)
WHERE
e.language_code = 'en'
;
Upvotes: 1
Reputation: 1269753
You can use not exists
and or
:
select t.id, t.language_code, t.name
from translations t
where t.language_code = 'fr' OR
(t.language_code = 'en' and
not exists (select 1 from translations t2 where t2.product_id = t.product_id and t2.language_code = 'fr'
));
Upvotes: 2