4

if both が be と評価されるOR節で使用される句の左端の条件の結果をどのように返すのか疑問に思ってい ました。LEFT JOINtrue

これまでに私が遭遇した解決策はどちらも、CASEステートメントを使用することを含みます。これは、節SELECTを放棄することを意味します。OR

もう 1 つの解決策CASEは、ORDER BY.

CASEステートメントの使用を減らす他の解決策はありますか。私が尋ねる理由は、現在または現在LEFT JOINs が 2 つしかないためですが、時間の経過とともにさらに追加されるためです。

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'

フランス語の説明が見つかる可能性が高い場合、最初のクエリはより効率的です (最初のサブクエリが成功した場合、2 番目のサブクエリは評価されません)。

では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) を使用してフランス語の説明を結合し、必要な場合にのみ英語の説明にフォールバックします。

の場合MySQL1st3rdクエリに違いはありません。

すべてのシステムで、複合インデックスを作成しますlanguage (item, language)

于 2009-08-04T16:18:03.633 に答える
2

代わりに In 句を使用するように複数の Or を変更できます...

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 に答える