当我使用右联接时,我得到的结果与使用左联接或仅联接相同。有人能告诉我哪里出了问题吗?
我有3张表如下:
语言
id
代码,例如"hu"、"en"
语言故障
id
文本
language_translations
id
lang_id(FK语言表中语言的id)
default_lang_id(FK语言默认表中文本的id)
文本(翻译)
当我执行以下查询时,我希望从language_translations表中获得所有匈牙利语翻译,并从language_default表中获得没有匈牙利语翻译的空值文本字段。
SELECT `language_translations`.`text`
, `language_default`.`text`
FROM `languages`
, `language_translations`
RIGHT JOIN `language_default` ON `language_default`.`id` = `language_translations`.`default_lang_id`
WHERE `languages`.`code` = 'hu'
AND `languages`.`id` = `language_translations`.`lang_id`
相反,我只从language_default表中获取文本,其中translsation表中有该文本的翻译。我希望这种行为来自左联接或正常联接,但不是右联接。有什么想法吗?为什么我没有从language_defilt表中获取所有条目?
首先,您以错误的方式使用了普通联接和权限联接的组合。您可以按照以下查询使用。
第二件事右连接意味着你将从右侧获得所有记录,从左侧获得相应的记录,如果左侧没有相应的记录那么它将显示NULL。
左联接是其反向联接。
普通联接或逗号联接将只提供公共行。
所以,如果表只有公共行,那么所有联接都将提供相同的结果。
SELECT
`language_translations`.`text` , `language_default`.`text`
FROM `languages` AS l
JOIN `language_translations` AS t
ON l.`id` = t.`lang_id` AND l.`code` = 'hu'
RIGHT JOIN `language_default` AS d
ON d.`id` = t.`default_lang_id`;
不要混合隐式联接和显式联接。一个简单的规则是:不要在from
子句中使用,
。下面将重构您的查询以使用left outer join
:
SELECT `language_translations`.`text`, ld.`text`
FROM language_default ld left outer join
language_translations lt
on ld.`id` = lt.`default_lang_id` left outer join
`languages` l
on l.`id` = lt.`lang_id` and l.`code` = 'hu' ;
当使用外部联接时,您需要非常小心附加条件的去向。驱动表上的条件(第一个是左外部联接,最后一个是右外部联接)可以放在where
子句中。对于其他表,条件应该放在on
子句中。否则,他们会将外部联接转换为内部联接,原因很简单,即(几乎)任何与NULL
的比较都相当于false。