SQL。当列不存在时,左连接和空值

时间:2017-02-12 21:31:26

标签: mysql sql database join left-join

我陷入了疑问。希望有人可以帮助我。

我有这4张桌子:

表:项目

id_items
1

表:items_atr_currencies_match

id_items_atr_currencies_match | id_items_atr_currencies | id_items
1                             | 1                       | 1

表:items_atr_currencies_translations

id_items_atr_currencies_translations | id_items_atr_currencies | id_language_code | translation
1                                    | 1                       | 1                | $

表:items_atr_currencies

id_items_atr_currencies
1   

表:语言

id_languages | language_code
1            | es
2            | en

我的查询:

SELECT
    id_items,
    iact3.translation AS currency

FROM
    items i

LEFT JOIN 
    items_atr_currencies_match AS iacm3 ON iacm3.id_items = i.id_items
LEFT JOIN 
    items_atr_currencies AS iac3 ON iac3.id_items_atr_currencies = iacm3.id_items_atr_currencies
LEFT JOIN 
    items_atr_currencies_translations AS iact3 ON iact3.id_items_atr_currencies = iacm3.id_items_atr_currencies 
LEFT JOIN 
    languages AS l ON l.id_languages = iact3.id_language_code OR iact3.id_language_code IS NULL

WHERE
    i.id_items = 1
    AND l.language_code = "en" 

预期结果:

id_items | currency
1        | null

获得0结果

我想我错过了像#34;或者iact3.id_language_code不存在"在最后一次LEFT JOIN中,但我不知道该怎么做。

当表items_atr_currencies_match没有数据或表items_atr_currencies_translations有翻译但没有数据并且翻译不存在时,它可以正常工作。

提前谢谢

*更新*

最后这个查询正在做我想要的事情:

SELECT 
     i.id_items,            
     iact3.translation AS currency

FROM
     items i

LEFT JOIN 
     languages AS l ON l.language_code = 'en'
LEFT JOIN 
     items_atr_currencies_match AS iacm3 ON iacm3.id_items = i.id_items
LEFT JOIN 
     items_atr_currencies_translations AS iact3 ON iact3.id_items_atr_currencies = iacm3.id_items_atr_currencies 
     AND l.id_languages = iact3.id_language_code            
LEFT JOIN items_atr_currencies AS iac3 ON iac3.id_items_atr_currencies = iacm3.id_items_atr_currencies

WHERE
    i.id_items = 1

我所要做的就是将语言LEFT JOIN移到第一位并检查那里的语言代码。

2 个答案:

答案 0 :(得分:0)

你有一系列left join个。当您在第一个表以外的任何表上的where子句中有条件时,它往往会将left join转换为inner join。您需要将该条件放在on子句中:

SELECT id_items,iact3.translation AS currency
FROM items i LEFT JOIN 
     items_atr_currencies_match AS iacm3
     ON iacm3.id_items = i.id_items LEFT JOIN 
     items_atr_currencies AS iac3 
     ON iac3.id_items_atr_currencies = iacm3.id_items_atr_currencies LEFT JOIN 
     items_atr_currencies_translations AS iact3
     ON iact3.id_items_atr_currencies = iacm3.id_items_atr_currencies  LEFT JOIN 
     languages AS l
     ON (l.id_languages = iact3.id_language_code OR iact3.id_language_code IS NULL) AND
        l.language_code = 'en' 
WHERE i.id_items = 1;

第一个表的条件放在WHERE子句中。

注意:我认为最后一个条件可以简化为:

     ON l.id_languages = iact3.id_language_code AND
        l.language_code = 'en' 

即使没有匹配,LEFT JOIN也会包含该行。

答案 1 :(得分:0)

您需要将条件AND l.language_code = "en"移动到左连接中。否则,将在评估完所有左连接后检查此条件,如果结果元组没有language_code = "en",则将从整体结果中删除它。

如果你现在想要currencies_translations仅在他们映射到有效语言时才被考虑,那么你必须先通过联接连接currencies_translationslanguages" left-接合"它与总体结果一起:

...
LEFT JOIN (select iact3.id_items_atr_currencies as iact3id from
    items_atr_currencies_translations AS iact3 JOIN 
    languages AS l ON (l.id_languages = iact3.id_language_code AND l.language_code = "en") OR iact3.id_language_code IS NULL) as iact3l 
    ON iact3l.iact3id = iacm3.id_items_atr_currencies