2009-08-04 15 views
4

句の左端の結果がLEFT JOINで使用されている場合は、両方ともtrueと評価された場合、どのように返すのだろうと思いました。LEFT JOINを使用してOR

これまでの解決策では、どちらもにCASEというステートメントを使用しています。これは、OR節を放棄することを意味します。

ORDER BYCASEステートメントを使用することに関連する他の解決策は、

CASEステートメントの使用を削減する他のソリューションはありますか?私が尋ねる理由は、今のところ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' 
+0

私はあなたの質問を理解していません... lang.dataとlang2.dataは常に同じことを返します。 – Martin

+0

なぜ同じジョイン基準でLanguageに2回参加していますか? –

+0

申し訳ありません私はサンプル文に 'lang.type'を含めませんでした。lang.type = 'NAME'、lang2.type = 'DESCRIPTION' – Andre

答えて

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' 

フランスの記述を発見する確率が高い場合には最初の問合せは、(最初​​の1が成功した場合、第2副問合せを評価しません)、より効率的です。

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 JOINまたはMERGE JOIN)を使用します。このクエリ、および必要な場合にのみ、英語にフォールバックします。

MySQLについては、1st3rdのクエリで違いはありません。すべてのシステムで

、たぶん、あなたはこのような何かしたいlanguage (item, language)

2

あなたが代わりに句で使用するために、複数のORSを変更することができます...

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

udfからリスト( 'fr'、 'en')を返すと、おそらく後で簡単に拡張できます。 –

+0

'const ='がリテラルとして提供されている場合、メジャーのすべての 'RDBMS'は' ID = IN(const1、const2) 'と' ID = const1 OR ID = const2'の同じ計画を生成します。 – Quassnoi

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' 

フランス語と英語の両方が存在する場合、またはフランス語のみが存在する場合、フランス語のデータを返します。 。

+0

あなたは正しいです。 :) – Andre

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