T-SQL 选择连接 3 个表
Posted
技术标签:
【中文标题】T-SQL 选择连接 3 个表【英文标题】:T-SQL Select Join 3 Tables 【发布时间】:2017-09-18 04:21:44 【问题描述】:我目前正在 SQL Server 2012 上的 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、EmployeeId
棘手的部分是实现版本控制。因此,随着时间的推移,项目成员可以更改,并且应该始终可以返回到以前的版本,这就是为什么我使用 MemberVersionId 作为 Project 和 成员。表 Project 和 ProjectData 与 ProjectDataId 链接。
因此,1 个项目有 1 个 OfferData,1 个项目有 N 个成员。
一些示例数据:项目
ProjectId | ProjectDataId | MemberVersionId |
----------+---------------+-----------------+
1 | 2 | 1 |
2 | 3 | 1 |
3 | 4 | 1 |
项目数据
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
不幸的是,这还不起作用。你知道如何解决这个问题吗?
谢谢
【问题讨论】:
添加所需的输出 今日提示:切换到现代、明确的JOIN
语法!更容易编写(没有错误),更容易阅读维护,如果需要更容易转换为外连接!
【参考方案1】:
这样的?
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;
【讨论】:
最佳答案。易于阅读、正确的连接、适当的表别名。 完美运行!感谢您的帮助!【参考方案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
【讨论】:
【参考方案3】:您必须选择两次成员,一次用于经理,一次用于联系人:
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
【讨论】:
【参考方案4】:试试这个,
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
【讨论】:
【参考方案5】:解决您的问题的最简单方法是将附加字段引入Project
表。您可以将其称为LatestMemberVersion
(int,拥有当前最高的 MemberVersionId),这将是关系的最新版本,您可以添加更简单的IsLatestMemberVersion
(位,如果记录为 1,则为最新的/活动的)。您可以使用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 和 2 结合起来
您可以尝试使用 SQL Server 功能,例如更改数据跟踪。但是我没有这方面的经验,所以它可能会一事无成。
最后一条建议,如果可以的话,永远不要将连接条件写入 WHERE 子句。它不可读,并且当您突然将 JOIN 更改为 LEFT JOIN 时可能会导致问题。 Microsoft 本身建议在适用时使用ON
而不是WHERE
。
【讨论】:
以上是关于T-SQL 选择连接 3 个表的主要内容,如果未能解决你的问题,请参考以下文章
用于从连接表中进行选择的 T-SQL 查询,其中有可变数量的参数?