takeshin
takeshin

Reputation: 50658

Setting defaults for empty fields returned in select

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

Answers (2)

dani herrera
dani herrera

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

Andomar
Andomar

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

Related Questions