LEFT JOIN使用OR

时间:2009-08-04 15:53:16

标签: sql join default-value

我想知道如果两者都评估为OR,我将如何返回LEFT JOIN中使用的true子句中最左边条件的结果。

到目前为止,我遇到的解决方案都涉及在CASE中使用SELECT语句,这确实意味着我放弃了OR条款。

另一个解决方案涉及在CASE中使用ORDER BY语句。

是否有任何其他解决方案可以减少CASE语句的使用。我问的原因是因为现在只有两个LEFT JOIN,但随着时间的推移会增加更多。

SELECT item.id,
       item.part_number,
       lang.data AS name,
       lang2.data AS description
  FROM item
       LEFT JOIN
       language lang
          ON     item.id = lang.item
             AND (lang.language = 'fr' OR lang.language = 'en')
       LEFT JOIN
       language lang2
          ON     item.id = lang2.item
             AND (lang2.language = 'fr' OR lang2.language = 'en')
 WHERE item.part_number = '34KM003KL'

5 个答案:

答案 0 :(得分:7)

似乎你想要一个法语描述,如果它存在,否则后退到英语。

SELECT  item.id,
        COALESCE(
        (
        SELECT  lang.data
        FROM    language l
        WHERE   l.item = i.id
                AND l.language = 'fr'
        ),
        (
        SELECT  lang.data
        FROM    language l
        WHERE   l.item = i.id
                AND l.language = 'en'
        )
        ) AS description
FROM    item i

,或者这个:

SELECT  item.id,
        COALESCE(lfr.data, len.data)
FROM    item i
LEFT JOIN
        language lfr
ON      lfr.item = i.id
        AND lfr.language = 'fr'
LEFT JOIN
        language len
ON      len.item = i.id
        AND len.language = 'en'

如果查找法语描述的概率很高(如果第一个子查询成功则不会评估第二个子查询),则第一个查询会更有效。

SQL ServerOraclePostgreSQL如果你有很多法语描述,这个可能会更有效率:

SELECT  item.id,
        COALESCE(
        lfr.data,
        (
        SELECT  lang.data
        FROM    language l
        WHERE   l.item = i.id
                AND l.language = 'en'
        )
        ) AS description
FROM    item i
LEFT JOIN
        language lfr
ON      lfr.item = i.id
        AND lfr.language = 'fr'

此查询将使用有效的方法(HASH JOINMERGE JOIN)加入法语描述,并且仅在必要时才会回退到英语。

对于MySQL1st3rd查询没有任何区别。

在所有系统中,在language (item, language)

上创建综合索引

答案 1 :(得分:2)

您可以更改多个Ors以使用In子句......

SELECT i.id, i.part_number, L1.data name, L2.data description 
FROM item i
   LEFT JOIN language L1 ON i.id = L1.item 
      AND L1.language In ('fr', 'en')
   LEFT JOIN language L2 ON i.id = L2.item 
      AND L2.language In ('fr', 'en')
WHERE i.part_number = '34KM003KL'

答案 2 :(得分:0)

也许你想要这样的东西:

SELECT item.id, item.part_number, COALESCE (lang.data, lang2.data) AS description 
FROM item AS item
LEFT JOIN language AS lang ON item.id = lang.item AND lang.language = 'fr'
LEFT JOIN language AS lang2 ON item.id = lang2.item AND lang2.language = 'en'
WHERE item.part_number = '34KM003KL'

如果法语和英语都存在,或者只有法语存在,那将返回法语数据。

答案 3 :(得分:0)

如果您希望法语翻译存在且英语作为二手选择,您可以为每种语言加入一次语言表:

select
   item.id, item.part_number, isnull(fr.data, en.data) as name
from
   item
   left join language fr on fr.item = item.id and fr.language = 'fr'
   left join language en on en.item = item.id and en.language = 'en'
where
   item.part_number = '34KM003KL'

答案 4 :(得分:0)

为什么不在WHERE子句中执行您的标准?

SELECT item.id, item.part_number, lang.data AS name, lang2.data AS description 
    FROM item AS item
    LEFT JOIN language AS lang ON item.id = lang.item 
    LEFT JOIN language AS lang2 ON item.id = lang2.item 
    WHERE item.part_number = '34KM003KL'
        AND (lang.language = 'fr' OR lang.language = 'en')
        AND (lang2.language = 'fr' OR lang2.language = 'en')