2009-10-12 118 views
1

我有一個數據庫,有問題和答案,可以翻譯成網站使用的所有語言。但是當一個問題還沒有被翻譯時,我想用英語來表達這個問題。所以一個類似gettext的行爲。如何優化這個SQL查詢?

這個我現在的SQL查詢看起來是這樣的:

SELECT * FROM questions_view WHERE `language` = "de" AND `#parent` IS NULL 
UNION 
SELECT * FROM questions_view WHERE `language` = "en" AND `#parent` IS NULL 
    AND id NOT IN (SELECT id 
        FROM questions_view 
        WHERE `language` = "de") 

但我覺得這是不是這樣做的最佳方式。有小費嗎?

+0

代碼的編碼習慣避免使用通配符*。如果你使用它,你正在爲自己建立陷阱。 – markus 2009-10-12 10:49:31

回答

2

此:

SELECT qi.* 
FROM (
     SELECT DISTINCT id 
     FROM questions_view 
     ) qd 
JOIN questions_view qi 
ON  qi.id = qd.id 
     AND qi.language = 
     COALESCE(
     (
     SELECT language 
     FROM questions_view qn 
     WHERE parent IS NULL 
       AND language = 'de' 
       AND qn.id = qd.id 
     ), 
     (
     SELECT language 
     FROM questions_view qn 
     WHERE parent IS NULL 
       AND language = 'en' 
       AND qn.id = qd.id 
     ) 
     ) 

或本:

SELECT COALESCE(qde.question_text, qen.question_text) 
FROM (
     SELECT DISTINCT id 
     FROM questions_view 
     ) qd 
LEFT JOIN 
     questions_view qde 
ON  qde.id = qd.id 
     AND qde.language = 'de' 
LEFT JOIN 
     questions_view qen 
ON  qen.id = qd.id 
     AND qen.language = 'en' 

如果這些查詢更好,哪一個取決於您的數據庫系統以及數據庫中有多少問題需要翻譯。

更多細節請參閱本系列文章在我的博客:

+0

謝謝你在這個系列。 MySQL文章提供了一個很好的解決方案。 – 2009-10-13 08:08:54

1

嗯。我想不出任何其他解決方案。你可能會設置languagenull如果問題還沒有翻譯,這將讓你修改如下:

select * from questions_view where `language` = "de" and `#parent` is null 
union 
select * from questions_view where `language` is null and `#parent` is null 

OTOH它可以幫助先翻譯問題添加到一個臨時表,然後執行「在德國「-check不存在作爲

and not exists (select 1 from temp_translated t where t.id = id) 
1

不知道,如果我是正確的,但不是這還不夠

select * from questions_view where language in ('de','en') and #parent is null 
+0

無論翻譯是否存在,這都會以德語和英語獲得。 – Paddy 2009-10-12 10:41:35

+0

明白了。試圖讓它現在正確。 – danish 2009-10-12 10:55:17

1

通過刪除存在並僅採用第一個可用答案,可能刪除1次到DB的旅程,例如

Select Top 1 * 
FROM 
(
    select 1 as myRank, * from questions_view where `language` = "de" and `#parent` is null 
    union 
    select 2 as myRank, * from questions_view where `language` = "en" and `#parent` is null 
) A 
Order By myRank asc 
1

我會去danish's answer,此外,而不是通配查詢,僅返回列名的您需要,而不是獲取它們。

Select col1, col2, col3, col_etc from questions_view where 
language in ('de','en') and #parent is null