Reputation: 50658
Given two tables:
image(id, cat_id, name)
image_translation(id, title, desc, lang)
(names and ids are unique)
Query to select all translations for the particular file:
SELECT c.id AS c__id,
c.cat_id AS c__cat_id,
c.name AS c__name,
c2.id AS c2__id,
c2.title AS c2__title,
c2.desc AS c2__desc,
c2.lang AS c2__lang,
FROM image c
LEFT JOIN image_translation c2
ON c.id = c2.id
WHERE ( c1.name = 'file.jpg' )
returns:
c__id | c__cat_id | c2__id | c__name | c2__title | cs__desc | c2__lang
------+------------+-----------+-----------+---------------+--------------+---------
114 | 2 | 114 | file.jpg | default title | default desc | en
114 | 2 | 114 | file.jpg | NULL | desc in de | de
114 | 2 | 114 | file.jpg | title in fr | '' | fr
To select the translation for the particular file in particular language, obviously I need to add the where clause.
But then it returns the default row content, which may contain empty fields in translation.
How can I merge the result with the default values and overwrite the empy fields with the default ones? The default values are returned for lang en:
SELECT c2.title AS c2__title,
c2.desc AS c2__desc,
c2.lang AS c2__lang,
FROM image c
LEFT JOIN image_translation c2
ON c.id = c2.id
WHERE ( c1.name = 'file.jpg' )
AND WHERE ( c2.lang = 'en')
Sample results I expect:
for german language:
-- AND WHERE ( c2.lang = 'de' )
c__id | c__cat_id | c2__id | c__name | c2__title | cs__desc | c2__lang
-----+------------+-----------+-----------+---------------+--------------+---------
114 | 2 | 114 | file.jpg | default title | desc in de | de
for french language:
-- AND WHERE ( c2.lang = 'fr' )
c__id | c__cat_id | c2__id | c__name | c2__title | cs__desc | c2__lang
-----+------------+-----------+-----------+---------------+--------------+---------
114 | 2 | 114 | file.jpg | title in fr | default desc | fr
How to do it right in one smart query?
(I use MySQL and Doctrine ORM with I18N behavior)
Upvotes: 3
Views: 145
Reputation: 51715
I don't know if you are asking for this simple query:
For 'fr':
SELECT c2.title AS c2__title,
coalesce( nullif( c2.desc, '') , c3.desc ) AS desc,
coalesce( nullif( c2.lang, '') , c3.lang ) AS lang,
FROM image c
LEFT JOIN image_translation c2
ON c2.lang = 'fr' and c.id = c2.id
LEFT JOIN image_translation c3
ON c3.lang = 'en' and c.id = c3.id
WHERE ( c1.name = 'file.jpg' )
Upvotes: 4
Reputation: 238246
You could do two left joins
, the second one looking for the default language. A case
could then decide between the two:
select case
when it1.title = '' or it1.title is null then it2.title
else it1.title
end as title
, case
when it1.desc = '' or it1.desc is null then it2.desc
else it1.desc
end as desc
from image i
left join
image_translation it1
on c.id = c2.id
and it1.lang1 = 'fr'
left join
image_translation it2
on c.id = c2.id
and it2.lang1 = 'en'
where i.name = 'file.jpg'
Upvotes: 2