我有这样的数据库结构:
国家
CREATE TABLE IF NOT EXISTS `countries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
`is_active` tinyint(1) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_5D66EBAD77153098` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
国家语言
CREATE TABLE IF NOT EXISTS `country_languages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`language_id` int(11) DEFAULT NULL,
`country_id` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_1532561982F1BAF4` (`language_id`),
KEY `IDX_15325619F92F3E70` (`country_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
语言
CREATE TABLE IF NOT EXISTS `languages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`iso` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`is_primary` tinyint(1) DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_A0D153795E237E06` (`name`),
UNIQUE KEY `UNIQ_A0D1537961587F41` (`iso`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
语言数据表:
id name iso
----------------------
1 English en
2 German de
3 Italian it
和国家/地区表:
id code
----------------
1 ie
和国家语言表
id country_id language_id name
----------------------------------------------
1 1 1 Ireland in English
2 1 2 Ireland in German
我正在尝试编写一个返回以下结果的查询,以便能够显示它。 (如果可能的话)
(Language) (Country name)
English Ireland in English
German Ireland in German
Italian #NULL OR EMPTY STRING
第二,我试图理解是否有可能将例如英语设置为默认语言,并且当不存在具有id 3(意大利语)的语言的内容时,默认值应该像这样回落:
(Language) (Country name)
English Ireland in English
German Ireland in German
Italian Ireland in English #please note language id is 3 -> Italian.
答案 0 :(得分:2)
好的,所以可以在没有子查询但是使用连接的情况下完成以下查询。我相信查询优化器会这样做,但我不太确定。
SELECT l.name as language,
(SELECT cl.name
FROM country_languages cl
WHERE cl.country_id=[the wanted country id]
ORDER BY cl.language_id=l.id DESC,
cl.language_id=1 DESC
LIMIT 1) as country_name
FROM languages l
在此版本中,language_id 1用作首选后备版,您可以以类似的方式添加更多语言。使用FIND_IN_SET
代替二阶标准也可以(FIND_IN_SET(cl.language_id,'1,2,3') DESC
或您喜欢的任何顺序)。
当然,此查询现在是针对固定的country_id。对于具有另一个联接的多个国家/地区,它可以以类似的方式进行扩展:
SELECT l.name as language,
(SELECT cl.name
FROM country_languages cl
WHERE cl.country_id=c.id
ORDER BY cl.language_id=l.id DESC,
cl.language_id=1 DESC
LIMIT 1) as country_name
FROM countries c
JOIN languages l
子查询的替代方法是两次加入country_languages,只选择第一个不为null的(这可能是更清洁的解决方案之一):
SELECT l.name as language,
COALESCE(first.name, second.name) as country_name
FROM countries c
JOIN languages l
LEFT JOIN country_languages first ON
(first.country_id=c.id AND first.language_id=l.id)
LEFT JOIN country_languages second ON
(second.country_id=c.id AND second.language_id=1)
如果语言ID为您的后备语言。这也可以扩展,以提供多种后备语言......
答案 1 :(得分:-1)
以下是使用连接的第一部分的查询:
SELECT `country_languages`.id, `country_languages`.country_id,`country_languages`.language_id, `country_languages`.name FROM `countries` left join country_languages on `countries`.id=`country_languages`.`country_id`
您可以在国家/地区语言表中声明状态列,并将状态设置为0,1,2,以标记获取方式的优先级。