2017-04-21 11 views
2

現在、SQL Server 2012のT-SQLで選択クエリを処理しています。複雑なクエリです。3つのテーブルからリストをクエリします。T-SQL結合3テーブルを選択します。

所望の出力:

ProjectId | Title | Manager | Contact | StatusId 
----------+-------------+-----------+-----------+----------- 
1   | projectX | 1123 | 4453  | 1 
2   | projectY | 2245 | 5567  | 1 
3   | projectZ | 3335 | 8899  | 1 

マイ3つのテーブル:

1)プロジェクト: PROJECTID、ProjectDataId、MemberVersionId
2)ProjectData:結果は次のようになります。 ProjectDataId、Title、StatusId
3)メンバー: MemberId、MemberVersionId、MemberTypeId、Emp loyeeId

トリッキーな部分は、バージョン管理を実装することです。したがって、プロジェクトメンバーは変更することができ、いつも以前のバージョンに戻ることができるはずです。そのため、MemberVersionIdプロジェクトメンバーの間で外部キーとして使用しています。 ProjectDataIdにリンクされたテーブルProjectとProjectData。

したがって、1つのプロジェクトには1つのOfferDataがあり、1つのプロジェクトにはN個のメンバーがあります。

いくつかのサンプルデータ:
プロジェクト

ProjectId | ProjectDataId | MemberVersionId | 
----------+---------------+-----------------+ 
1   | 2   | 1    | 
2   | 3   | 1    | 
3   | 4   | 1    | 

ProjectData

ProjectDataId | Title | StatusId 
--------------+-------------+----------- 
2    | projectX | 1 
3    | projectY | 1 
4    | projectZ | 1 

メンバー: MemberTypeId 1 =マネージャー、=その他

MemberTypeId 2 =連絡先、3
MemberId | MemberVersionId | MemberTypeId | EmployeeId | 
---------+-----------------+--------------+------------+ 
1  | 1    | 1   | 1123  | 
2  | 1    | 2   | 4453  | 
3  | 1    | 3   | 9999  | 
4  | 2    | 1   | 2245  | 
5  | 2    | 2   | 5567  | 
6  | 2    | 3   | 9999  | 
7  | 3    | 1   | 3335  | 
8  | 3    | 2   | 8899  | 
9  | 3    | 3   | 9999  | 

私の現在のクエリは次のようになります。

SELECT ProjectId, Title, EmployeeId AS Manager, EmployeeId AS Contact, StatusId 
FROM [MySchema].[Project] a, 
    [MySchema].[ProjectData] b, 
    [MySchema].[Members] c 
WHERE a.ProjectDataId = b.ProjectDataId 
    AND a.MemberVersionId = c.MemberVersionId 

残念ながら、これはまだ動作しません。あなたはこの問題を解決する方法を知っていますか?

おかげ

+2

希望の出力を追加 –

+2

今日のヒント:現代的で明示的な 'JOIN'構文に切り替えてください!書き込みが簡単(エラーなし)、メンテナンスを読みやすく、必要に応じて外部結合に変換しやすくなりました。 – jarlh

答えて

4

何か?

SELECT 
    p.ProjectId, 
    pd.Title, 
    mm.EmployeeId AS Manager, 
    mc.EmployeeId AS Contact, 
    pd.StatusId 
FROM 
    [MySchema].[Project] p 
    INNER JOIN [MySchema].[ProjectData] pd ON pd.ProjectDataId = p.ProjectDataId 
    INNER JOIN [MySchema].[Members] mm ON mm.MemberVersionId = p.MemberVersionId AND mm.MemberTypeId = 1 
    INNER JOIN [MySchema].[Members] mc ON mc.MemberVersionId = p.MemberVersionId AND mc.MemberTypeId = 2; 
+0

ベストアンサーに選ばれました。読みやすく、適切な結合、適切なテーブルのエイリアス –

+0

完璧に動作します!ご協力いただきありがとうございます! – TimHorton

2

あなたはこれを試すことができます。このような

SELECT ProjectId, Title, C.EmployeeId AS Manager, d.EmployeeId AS Contact, StatusId 
FROM [MySchema].[Project] a 
INNER JOIN [MySchema].[ProjectData] b ON A.ProjectDataId=B.ProjectDataId 
LEFT JOIN (SELECT * FROM [MySchema].[Members] WHERE MemberTypeID=1) c ON a.MemberVersionId=c.MemberVersionId 
LEFT JOIN (SELECT * FROM [MySchema].[Members] WHERE MemberTypeID=2) d ON a.MemberVersionId=d.MemberVersionId 
2

あなたはメンバーを2回、管理者用との接触のための別の選択する必要があります:あなたの問題の最も簡単な解決策が追加導入されるだろう

SELECT ProjectId, Title, cmanager.EmployeeId AS Manager, ccon.EmployeeId AS 
Contact, StatusId 
from [MySchema].[ProjectData] b 
inner join [MySchema].[Project] a on b.ProjectDataId=a.ProjectDataId 
left join [MySchema].[Members] cmanager on cmanager.MemberVersionId = 
    a.MemberVersionId and cmanager.MemberTypeId=1 
left join [MySchema].[Members] ccon on ccon.MemberVersionId = 
a.MemberVersionId and ccon.MemberTypeId=2 
2

をフィールドをProjectに設定します。あなたはそれをLatestMemberVersion(int、現在の最も高いMemberVersionIdを保持している)と呼んでいます。これは最も最新のバージョンの関係で、さらに簡単に追加することができますIsLatestMemberVersion(ビットは、レコードが最新/アクティブ)。 ROW_NUMBER() OVERステートメントを使用して両方を計算できます。

その後、クエリがに変更します

SELECT ProjectId, Title, EmployeeId AS Manager, EmployeeId AS Contact, StatusId 
FROM [MySchema].[Project] a, 
    [MySchema].[ProjectData] b ON a.ProjectDataId = b.ProjectDataId 
    [MySchema].[Members] c ON a.MemberVersionId = c.MemberVersionId 
WHERE 
a.[IsLatestMemberVersion] = 1 -- alternative is a.[LatestMemberVersion] = a.[MemberVersionId] 

また、あなたが試すことができる2つの以上のものがあります:

  1. あなたはつまり、あなたがする、データウェアハウスからアイデアを借りたいかもしれません緩やかに変化するディメンションタイプ1と2の組み合わせが必要です

  2. 変更データトラッキングなどのSQL Server機能を使用できます。しかし、私はそれを経験していないので、どこにもつながりません。

最後に、WHERE節に結合条件を書くことはできません。 JOINをLEFT JOINに突然変更すると、読み込みができず、問題につながる可能性があります。マイクロソフト自身でWHEREの代わりにONを使用することをお勧めします。

2

、これを試してみてください

SELECT ProjectId, Title, m.EmployeeId AS Manager, c.EmployeeId AS 
    Contact, StatusId 
FROM [MySchema].[Project] a, 
    [MySchema].[ProjectData] b, 
    [MySchema].[Members] m 
    [MySchema].[Members] c 
WHERE a.ProjectDataId = b.ProjectDataId 
    AND a.MemberVersionId = m.MemberVersionId and m.MemberTypeId = 1 
    AND a.MemberVersionId = c.MemberVersionId and c.MemberTypeId = 2 
関連する問題