2014-01-24 51 views
0

1行我有3個表:選擇從2項連接成

手冊:

ManualId | Stuff... 
---------+---------- 
180  | Stuff... 

ManualLang:

ManualLangId | ManualId | LangId | Description 
-------------+----------+--------+----------------------- 
1   | 180  | FR-CA | Description française 
2   | 180  | EN-CA | English description 

郎鹹平:

LangId 
--------- 
FR-CA 
EN-CA 

我使用語言表來輕鬆添加新的l語言與我的應用程序(s)。 manualLang表在那裏允許我的手動屬性具有不同的語言,而無需複製我的手冊,並避免在我的手動表中使用不同語言的大量屬性。而且,它將使我在將來更容易以這種方式添加新語言,而無需修改所有表以添加語言。

但我有一個問題。在我的MVC網站上,我需要用它的語言來獲得手冊。因此,爲了做到這一點,我必須做出一個選擇查詢將返回我:

Manual_Id | DescriptionFr   | DescriptionEn 
----------------------------------|--------------------- 
180  | Description française | English description 

到目前爲止,我可以讓我的結果與此查詢

SELECT m.ManualId, 
      mlFr.Description as 'DescriptionFr', 
      mlEn.Description as 'DescriptionEn' 
FROM Manual m 
left join ManualLang mlFr ON m.ManualId = mlFr.ManualId 
left join ManualLang mlEn ON m.ManualId = mlEn.ManualId 
WHERE m.ManualId = 180 AND mlFr.LangId = 'FR-CA' AND mlEn.LangId = 'EN-CA' 

我的問題是.. 。有沒有可能以更清潔的方式做到這一點?

我應該使用一段時間嗎? CTE?一個光標?或者這是我應該這樣做的方式?我將不得不在我的應用程序中複製此許多其他查詢。

回答

2

我認爲這是一個明確的解決方案。您可以更改查詢以將連接謂詞移動到join而不是where。就這樣。

select m.ManualId 
,  mlFr.Description as DescriptionFr 
,  mlEn.Description as DescriptionEn 
from Manual m 
left 
outer 
join ManualLang mlFr 
on  m.ManualId = mlFr.ManualId 
and  mlFr.LangId = 'FR-CA' 
left 
outer 
join ManualLang mlEn 
and  mlEn.LangId = 'EN-CA' 
on  m.ManualId = mlEn.ManualId 
where m.ManualId = 180 
+0

是的,我應該這樣做,這是好還是戈登·利諾夫更好的解決方案? – snaplemouton

+0

很難說。我會說我的表現更好,但這是一個有教養的猜測。我會說:讓解釋計劃決定! :) –

+0

在SQL服務器上測試它們兩個之後,這個版本的速度非常慢,但是需要較少的字節傳輸,所以我將使用這個版本。 – snaplemouton

1

您可以用單個連接和aggregataion做到這一點:

SELECT m.ManualId, 
     max(case when ml.LangId = 'FR-CA' then ml.Description end) as DescriptionFr, 
     max(case when ml.LangId = 'EN-CA' then ml.Description end) as DescriptionEn 
FROM Manual m left join 
    ManualLang ml 
    ON m.ManualId = ml.ManualId 
WHERE m.ManualId = 180 AND ml.LangId in ('FR-CA', 'EN-CA') 
GROUP BY m.ManualId; 

注意:您應該只爲字符串常量列名使用單引號,不是。

編輯:

這個版本讓我們得到你所需要的一切:

SELECT m.*, ml.DescriptionFr, ml.DescriptionEn 
FROM Manual m left join 
    (select ml.ManualId, 
      max(case when ml.LangId = 'FR-CA' then ml.Description end) as DescriptionFr, 
      max(case when ml.LangId = 'EN-CA' then ml.Description end) as DescriptionEn 
     from ManualLang ml 
     where ml.ManualId = 180 and ml.LangId in ('FR-CA', 'EN-CA') 
     group by ml.ManualId 
    ) ml 
    ON m.ManualId = ml.ManualId; 
+0

我覺得我忘了GROUP BY ._。這項工作完全謝謝你。 :) – snaplemouton

+0

在我的應用程序嘗試這個之後,它有一個小問題。我的手工表得到了更多的只是ManualId,並獲得了大約20個不同的屬性,我需要通過SELECT m。*而不是m.ManualId來獲得選擇。有沒有辦法通過手冊中的所有行來創建GROUP BY組? – snaplemouton

+0

感謝您的編輯,它現在很好,很乾淨。 :) – snaplemouton