MySQL : ORDER BY FIELD / GROUP BY
MySQL : ORDER BY FIELD / GROUP BY
我的问题是关于MySQL优化和良好的实践。\n我需要获取一个已排序的翻译文本列表:如果我找不到英文文本,我想使用法文文本,如果法文文本不存在,我想使用西班牙文。\n换句话说,我有以下数据:\n
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
\n我想要的结果是:\n
id lang text 1 en text_EN 2 fr text_FR2 3 fr text_FR3
\n所以我阅读了一些类似于这个,这个,那个,或者那个的主题。好的。\n我尝试了这个:\n
SELECT text FROM ( SELECT id, text FROM translation ORDER BY FIELD(lang, 'en', 'fr', 'es') ) tt GROUP BY tt.id;
\n但是,当我解释这个查询时,我可以看到:\n
id select_type table partitions type possible_keys key key_len ref rows Extra 1 PRIMARYNULL ALL NULL NULL NULL NULL 4 Using temporary; Using filesort 2 DERIVED translation NULL ALL PRIMARY PRIMARY 52 1641 Using filesort
\n所以,这不是优化的,因为有子查询。我能避免这个子查询吗?
MySQL中的一个常见问题是如何按照指定的顺序进行排序或分组。在处理多语言数据时,我们可能需要按照指定的语言顺序进行排序或者将数据按照指定的语言进行分组。
在上述问题中,我们可以使用ORDER BY FIELD来实现按照指定顺序进行排序。使用GROUP BY可以将数据按照指定的语言进行分组。
解决方法如下:
首先,我们可以使用LEFT JOIN将多个语言的数据表连接在一起,连接的条件是id相同。通过使用COALESCE函数,我们可以在连接的结果中选择第一个非空的文本值。
然后,我们可以使用GROUP BY将连接结果按照id进行分组。
下面是解决方法的实现代码:
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
在解决问题的过程中,我们还学习到了COALESCE函数的用法,该函数可以在连接结果中选择第一个非空的文本值。