使用相同的外键但不同的值从同一个表中检索列

时间:2012-05-21 22:44:13

标签: mysql select union left-join outer-join

这是一个非常微妙的问题,但我会尽力说清楚:

我有一个包含3列的表countrynames:iso,lang,name。 这些的主要拼写是英语,例如:

+-----+------+-----------------------------+
| iso | lang | name                        |
+-----+------+-----------------------------+
| CA  | EN   | Canada                      |
| CC  | EN   | Cocos (Keeling) Islands     |
| CF  | EN   | Central African Republic    |
| CG  | EN   | Congo                       |
| CI  | EN   | Cote d'ivoire (Ivory Coast) |
| CK  | EN   | Cook Islands                |
| CL  | EN   | Chile                       |
| CM  | EN   | Cameroon                    |
| CN  | EN   | China                       |
| CO  | EN   | Colombia                    |
+-----+------+-----------------------------+

iso是引用国家iso-3166编码的外键。

我插入了一些英文拼写的国家,但只有当拼写与英语不同时,才能用其他语言插入,以便在数据库中节省一些空间(例如德语中的“德国”是“Deutschland”,所以'DE'的iso在表中出现两次,有两个不同的名字。)

我需要的是选择某些特定语言的所有国家(如德语或西班牙语),然后选择同一列中英语名称的所有国家/地区。如果外语中没有相应的名字,那么英文名称应该填空字段,这样我就会得到英语+外语的混合。混合应该等于具有英语拼写的国家的总和,像这样(空名是英语名称应该填写缺少的西班牙语名称,如刚果,智利,中国,哥伦比亚):

'CA', 'ES', 'Canadá'
'CC', 'ES', 'Islas Cocos'
'CD', 'ES', 'República Democrática del Congo'
'CF', 'ES', 'República Centroafricana'
NULL, NULL, NULL
'CH', 'ES', 'Suiza'
'CI', 'ES', 'Costa del Marfil'
'CK', 'ES', 'Islas Cook'
NULL, NULL, NULL
'CM', 'ES', 'Camerún'
NULL, NULL, NULL
NULL, NULL, NULL
NULL, NULL, NULL
NULL, NULL, NULL

这是我到目前为止所使用的:

select result2.iso, result2.lang, result2.name from (select result1.* from (select  t1.*
from (
select iso, lang, name from countrynames where lang = 'es') t1
right join
(select iso, lang, name from countrynames where lang = 'en') t2
on t1.iso = t2.iso) result1) result2;

1 个答案:

答案 0 :(得分:0)

您的原始SELECT可以简化一点:

SELECT t1.iso, t1.lang, t1.name
  FROM (SELECT * FROM countrynames WHERE lang = 'ES') t1
  RIGHT JOIN (SELECT * FROM countrynames WHERE lang = 'EN') t2
  ON t1.iso = t2.iso;

然后您需要做的就是合并列结果,因此如果t2中没有值,则检索t1值:

SELECT COALESCE(t1.iso, t2.iso), COALESCE(t1.lang, t2.lang), COALESCE(t1.name, t2.name)
  FROM (SELECT * FROM countrynames WHERE lang = 'ES') t1
  RIGHT JOIN (SELECT * FROM countrynames WHERE lang = 'EN') t2
  ON t1.iso = t2.iso;