2013-06-26 5 views
1

Я две таблицы следующим образом:РЕГИСТРИРУЙТЕСЬ только если столбец NULL

tag таблицы (теги только на английском языке):

ID title 
------------- 
1  tag_1 
2  tag_2 
3  tag_3 

tag_translation стол:

ID title  locale tag_id (foreign key) 
----------------------------------------------- 
1  tag_1_fr FR  1 
2  tag_1_de DE  1 
3  tag_2_es ES  3 

Как сделать SQL-запрос, возвращающий все теги на французском языке, и если ни один тег не найден на французском языке, откиньтесь на английский?

Пример результата (выбрать все тэги на французском, резервными на английский):

ID title 
--------------- 
1  tag_1_fr 
2  tag_2 
3  tag_3 
+0

Является ли ваш пример неправильным? Должен ли второй tag_id в вашем 2-м наборе быть 1? –

+0

@Goat_CO вы правы, исправлены. –

+0

Итак, английский язык существует для всех тегов, но не в таблице переводов? –

ответ

6
SELECT T.ID 
     ,COALESCE(TT.TITLE, T.TITLE) AS TITLE 
FROM tag T 
LEFT JOIN tag_translation TT 
    ON T.ID = TT.tag_id 
    AND TT.locale = 'FR'; 

Это предполагает, что tag_id и локали являются уникальными в tag_translation.

+1

Демо-версия: http://sqlfiddle.com/#!1/cb703/3/0 –

3

Попробуйте это с выражением CASE:

SELECT 
    T.ID, 
    CASE 
     WHEN TT.locale IS NOT NULL AND TT.locale = 'FR' THEN TT.title 
     ELSE t.title 
    END title 
FROM tag T LEFT JOIN tag_translation TT ON T.ID = TT.tag_id 
+0

Помните, что если у вас есть несколько тегов перевода, будет дублирование, например, на [this fiddle] (http://sqlfiddle.com/#!1/66ed2/1) тег 1 имеет перевод на английском и немецком языках, что приводит к отображению 3 строк для тега 1. Это можно решить, переместив 'AND TT.locale = 'FR'' в условие соединения [подобное этому] (http://sqlfiddle.com/#!1/66ed2/2) – GarethD

+0

@Yuck Будет проще использовать 'COALESCE' вместо' CASE WHEN'. Вам действительно нужно переместить 'TT.locale = 'FR'' в условие соединения. –

2

COALESCE вы должны получить то, что вы после этого.

drop table if exists tag, tag_translation; 

create table tag (
id int primary key, 
title text 
); 

insert into tag values (1,'tag_1'), (2, 'tag_2'), (3, 'tag_3'); 

create table tag_translation (
id  int, 
title text, 
locale text, 
tag_id int references tag (id) 
); 

insert into tag_translation values 
(1,'tag_1_fr', 'FR', 1), 
(2,'tag_1_de', 'DE', 1), 
(3,'tag_2_es', 'ES', 3); 


select id, coalesce(fr.title, en.title) as title 
from 
(select id, title from tag) as en 
left join (select id, title from tag_translation where locale = 'FR') as fr using (id) 


id | title 
----+---------- 
    1 | tag_1_fr 
    2 | tag_2 
    3 | tag_3 
+0

Действительно ?. Несмотря на то, что «COALESCE» можно было использовать как-то здесь, это, безусловно, не решает его проблемы. – Lamak

+2

@Lamak. Я вижу ответ, который использует «COALESCE» для решения проблемы. И это действительно решает. –

+0

Смешно ... Я ожидал, что postgres будут жаловаться, что 'id' неоднозначно в вашем последнем запросе ... else +1. –