LEFT JOIN using OR
问题描述:
我想知道如何将中使用的OR
子句中的最左边条件的结果返回,如果两者都评估为true
。LEFT 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'
答
看来想要一个法国人的描述,如果它存在,否则退回到英语。
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 Server
,Oracle
和PostgreSQL
这事实上如果你有很多法国人描述的更高效:
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 JOIN
或MERGE JOIN
)加入法国的描述,以及只有在必要时才会回到英文版。
对于MySQL
,1st
和3rd
查询没有区别。
在所有系统上创建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')
我不明白您的查询...... lang.data和lang2.data总是会返回同样的事情。 – Martin 2009-08-04 16:03:53
你为什么要用相同的连接标准加入语言两次? – 2009-08-04 16:05:26
对不起,我没有在样本声明中加入'lang.type'。它应该是lang.type ='NAME'和lang2.type ='DESCRIPTION' – Andre 2009-08-04 16:29:16