2017-12-13 8 views
0

はじめに:私は達成できないことをしていることを恐れています。しかし、それを行う方法があれば、ここに誰かが知っていることを知っています:)行が見つからない場合のJOIN条件のフォールバック値

私はMySQLデータベース(または互換性が保持できる場合は、MariaDBのもの)を持っているとします。 TableAから選択し、特定の値Xを持つ特定の列に基づいてTableBを結合する必要があります。 TableBに適切な行が存在しない可能性があります。つまり、LEFT OUTER JOINを使用します。しかし、行が見つからない場合(TableBの行にはその列に値Xがありません)、値Yを持つTableBの行を使用します。つまり、YはJOINのフォールバック条件として動作する必要があります。

これは具体的な例です。たとえば、ローカライズ可能なデータと固定データの2つのテーブル間でエンティティ(製品など)を分割してデータのローカライズを処理するとします。フランス語で製品情報を入手したい場合は、フランス語で情報が入手できない場合は、英語にフォールバックしたいと考えています。何のフランス語の情報が利用できない場合しかし、私は

// basic stub of the query for demonstration purposes 
SELECT * FROM Products p 
LEFT OUTER JOIN ProductsLocalization pLoc 
     ON pLoc.ProductID = p.ID AND pLoc.Culture = 'fr-FR' 

を行う場合、私はNULLを取得します。代わりに、それらの行のみ、私はクエリの結果を持っています。

// basic stub of the query for demonstration purposes 
SELECT * FROM Products p 
LEFT OUTER JOIN ProductsLocalization pLoc 
     ON pLoc.ProductID = p.ID AND pLoc.Culture = 'en-US' 

しかし、後者のクエリは当然受け入れられません。

カルチャー「fr-FR」または「en-US」に基づいてORを使用することができますが、これは選択された行の数を2倍にする可能性があり、投稿する必要があります - 得られたデータセットを処理する。この後処理を避ける方法があるかどうかを知りたい。

重複しない免責事項:私の質問は他の多くのものと似ていますが、重要な違いがあります。クエリの結果ではなく、JOIN条件自体にフォールバック値を使用する必要があります。私のデフォルトはデータセットには終わりませんが、データセットはそのデフォルトに基づいて計算されます。

+0

MySQLとMariaDBの違いはごくわずかなので、ここでクエリに影響はありません。 – tadman

答えて

1

あなたは二回参加して、必要な値を取得するために()COALESCEを使用することができます。

SELECT p.product_desc, 
    COALESCE(pLoc_fr.value, pLoc_en.value) 
FROM Products p 
    LEFT OUTER JOIN ProductsLocalization pLoc_us ON 
     pLoc_us.ProductID = p.ID 
     AND pLoc_us.Culture = 'en-US' 
    LEFT OUTER JOIN ProductsLocalization pLoc_fr ON 
     pLoc_fr.ProductID = p.ID 
     AND pLoc_fr.Culture = 'fr-FR'; 

をまた、あなたがデータセットを組み合わせる方法を想像することができるならば、あなたはおそらく、プレーンオールSQLを使用して達成することができます。いくつかのエッジケースでは、SQL文を動的に生成する必要がありますが、それほど一般的ではありません。この場合、COALESCEまたはCASE内の2つの相関サブクエリ、またはSELECT内のIF文を使用することもできます。ほとんどの場合、猫の皮膚にはいくつかの方法があります。

+0

私はCOALESCE()の力をあまりにも忘れています。あなたの答えをありがとう:それは動作し、私はそれを正しいとマークしています。 – Simone

関連する問題