LEFT JOIN using OR

问题描述:

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

我到目前为止所使用的解决方案均涉及在SELECT中使用CASE声明,这意味着我会放弃OR子句。

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

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

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' 
+0

我不明白您的查询...... lang.data和lang2.data总是会返回同样的事情。 – Martin 2009-08-04 16:03:53

+0

你为什么要用相同的连接标准加入语言两次? – 2009-08-04 16:05:26

+0

对不起,我没有在样本声明中加入'lang.type'。它应该是lang.type ='NAME'和lang2.type ='DESCRIPTION' – Andre 2009-08-04 16:29:16

看来想要一个法国人的描述,如果它存在,否则退回到英语。

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)

你可以改变多个厄尔斯使用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' 

一个综合指数也许你想是这样的:

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' 

如果法语和英语存在,或者只是法国人的存在,将返回法国数据。

如果你想法语翻译,如果它存在,而英语作为第二手的choise,您可以为每种语言一次参加语言表:

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' 

为什么你不只是做你的标准, 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')