2013-10-29 188 views
5

我的問題是關於MySQL優化和良好實踐。MySQL:ORDER BY FIELD/GROUP BY

我必須得到訂單偏好的翻譯文本列表:如果我找不到英文文本,我想使用法文文本,如果它不存在,我想用西班牙文。

換句話說,我有:

id lang text 
1 fr text_FR 
1 en text_EN 
1 es text_ES 
2 fr text_FR2 
3 fr text_FR3 
3 es text_ES3 

而且我想:

id lang text 
1 en text_EN 
2 fr text_FR2 
3 fr text_FR3 

所以我讀了一些主題,比如thisthisthat,或that。好。 我嘗試這樣做:

SELECT text FROM (
    SELECT id, text 
    FROM translation 
    ORDER BY FIELD(lang, 'en', 'fr', 'es') 
) tt GROUP BY tt.id; 

但是,當我解釋這個查詢,我可以讀:

id select_type table partitions type possible_keys key key_len ref rows Extra 
1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 4 Using temporary; Using filesort 
2 DERIVED translation NULL ALL PRIMARY PRIMARY 52  1641  Using filesort 

所以它不是最優化的,因爲子查詢。我可以避免這個子查詢嗎?

回答

2

我建議JOIN對每種語言id的表格。您可以使用LEFT JOIN來允許空結果。該查詢仍將使用臨時/ filesort,因爲它必須掃描整個表(您可以使用WHERE來限制它),但僅限於第一個表。在連接表上查找應該很快。

SELECT 
    COALESCE(en.text, fr.text, es.text, any.text) 
FROM 
    f any 
    LEFT JOIN f en ON (any.id = en.id AND en.lang = 'en') 
    LEFT JOIN f fr ON (any.id = fr.id AND fr.lang = 'fr') 
    LEFT JOIN f es ON (any.id = es.id AND es.lang = 'es') 
GROUP BY any.id; 

http://sqlfiddle.com/#!2/baafc/1

+0

有趣,不知道'COALESCE'! – xiankai