2017-04-21 129 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