2016-10-04 17 views
1

私は製品のテーブルと、それらの製品のさまざまな翻訳をリストした別のテーブルを持っています。基本的な設定は次のようなものになります。翻訳のSQL平坦化テーブル

dbo.Products 
ProductID | Description 
1   | An amazing product 
2   | An even more amazing product 
3   | Don't buy this one 

dbo.ProductTranslations 
ProductID | Language | Description 
1   | EN-US | null 
1   | FR-CA | Un produit étonnant 
2   | EN-US | null 
2   | FR-CA | Un produit encore plus étonnant 
3   | EN-US | null 
3   | FR-CA | Ne pas acheter celui-ci 

を私は何をしたいのですが、基本的にそのすべての製品および翻訳は一つのテーブルであり、このような各製品の単一の行に凝縮それを平らにされています

dbo.FlattenedProducts 
ProductID | EN-US_Description   | FR-CA_Description 
1   | An amazing product   | Un produit étonnant 
2   | An even more amazing product | Un produit encore plus étonnant 
3   | Don't buy this one   | Ne pas acheter celui-ci 

私はピボットについてthis oneと最高の提案(性能面で)case文のスルーを使用しているように見えるthis oneのような例を挙げて掘ってきましたが、私は私の状況に適用するために苦労しています。 2番目のリンクのようなcase文を使用すると、翻訳を線形にすることができますが、アイテムの総数は減らされません。私は4,000万行(そして最終的には十数個の結合)で作業しているので、速度は重大であり、このすべてのデータから選択したものを使用するだけでパフォーマンスが低下するため、select文からデータを消し去る必要があります。

これにいくつかのトリックがありますか?

編集:私は時々あり、それは「EN-US」だ際に翻訳の説明では、実際の値は、(私はこれを設計していなかった、なぜ質問しない)であり、それらはオリジナルを上書きする必要があることに注意してください私はちょうどSELECT WHERE Language != 'EN-US'またはそれに類するものではありません。また、英語とフランス語以外の言語もありますが、デモンストレーションの目的で単純化しました。

答えて

1

商品表から英語の説明を返す必要があるようです。条件付き和集合を使用します。

SELECT 
    p.ProductID, 
    MAX(CASE WHEN pt.Language = 'EN-US' THEN COALESCE(pt.Description, p.Description) END) AS ENUS_Description, 
    MAX(CASE WHEN pt.Language = 'FR-CA' THEN pt.Description END) AS FRCA_Description 
FROM dbo.Products p 
LEFT JOIN dbo.ProductTranslations pt ON p.ProoductID = pt.ProductID 
GROUP BY p.ProductID 

編集:は、翻訳テーブルから英語への翻訳に高い優先順位を与えるためにあなたの編集ごとにCOALESCE()を追加しました - それがnullだ場合、製品テーブルから元の記述を取ります。

他の言語の場合は、FR-CAのようになりますが、言語の値が異なる対応する行を追加してください。

+0

好奇心で、そこにある 'GROUP BY'ステートメントの目的は何ですか?私はそれを残して私はエラーが発生しますが、私はなぜそれが必要なのか分からない。 – thanby

+1

各グループ(ここではProductID)に対して1行を返します。次に、MAX()のような集計関数を使用して、指定されたグループの最大値を指定します(言語ごとに1つしかありません)。 –

1

最も簡単かつ最速の条件付き集約または結合のいずれかである:あなたがテーブルを作成する場合はinto FlattenedProductsを追加することができます

select pt.productid, 
     max(case when language = 'EN-US' then description end) as en_us, 
     max(case when language = 'CA-FR' then description end) as ca_fr 
from ProductTranslations pt 
group by productid; 

が。

join方法は次のとおりです。

select coalesce(pte.productid, ptf.productid) as productid, 
     pte.description as us_en, 
     ptf.description as ca_fr 
from ProductTranslations pte full join 
    ProductTranslations ptf 
    on pte.productid = ptf.productid and 
     pte.language = 'EN-US' and ptf.language = 'CA-FR'; 

これは、すべての製品を返します。各製品に各翻訳が少なくとも1つあることがわかっている場合は、full joinではなくinner joinを使用してください。より効率的です。

+0

これらの答えはどちらも素晴らしいです。私は両方を受け入れることができたらいいと思います。ご協力いただきありがとうございます。 – thanby

関連する問題