4

我想知道如何返回 if both evaluate to be中OR使用的子句中最左边条件的结果。LEFT JOINtrue

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

另一个解决方案涉及CASEORDER BY.

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

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'
4

5 回答 5

8

似乎您想要法语描述(如果存在),否则回退到英语。

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,如果你有很多法语描述OraclePostgreSQL这个可能会更有效:

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)

于 2009-08-04T16:18:03.633 回答
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'
于 2009-08-04T15:57:11.010 回答
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'

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

于 2009-08-04T16:21:32.677 回答
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'
于 2009-08-04T16:24:21.967 回答
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')
于 2009-08-04T16:28:53.177 回答