2017-04-21 130 views
2

我目前正在使用SQL Server 2012上的T-SQL進行選擇查詢。這是一個複雜的查詢,我想查詢3個表中的列表。結果應該是這個樣子:T-SQL Select加入3個表

所需的輸出:

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

我的3個表:

1)項目:專案編號,ProjectDataId,MemberVersionId
2)ProjectData的: ProjectDataId,Title,StatusId
3)成員: MemberId,MemberVersionId,MemberTypeId,Emp loyeeId

棘手的部分是,要實現版本控制。因此,隨着時間的推移,項目成員可以改變,並且始終可以回到以前的版本,這就是爲什麼我使用MemberVersionId作爲外鍵項目成員。表Project和ProjectData與ProjectDataId鏈接。

因此,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

添加所需的輸出 – 2017-04-21 08:51:26

+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

您必須選擇成員兩次,一個用於管理,另一個用於聯繫:

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 
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] 

此外,有兩兩件事你可以嘗試:

  1. 您可能希望從數據倉庫借用思路,即你會想要組合漸變維度類型1和2

  2. 您可以嘗試使用SQL Server功能,例如更改數據跟蹤。但是我沒有這方面的經驗,所以有可能會導致無處不在。

如果可以,最後一條建議永遠不要將連接條件寫入WHERE子句。這是不可讀的,並且當您突然將JOIN更改爲LEFT JOIN時會導致問題。適用時,Microsoft本身建議使用ON而不是WHERE