2013-06-26 59 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應該是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

請注意,如果您有多個翻譯標記,則會出現重複,例如[此小提琴](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'在您最後的查詢中不明確......其他+1。 –

相關問題