【发布时间】:2019-02-01 19:48:12
【问题描述】:
我没有更好的标题,而且我已经找到了解决方案 - 我想知道是否有更优雅的方法来解决这个问题,因为我不太喜欢我这样做的方式。
问题是:我有一些项目(我们称之为人员)与两个不同的事物(我们称之为部门和协会)存在 m:n 关系。假设人 1 是部门 1 和 2 以及协会 1 的成员,人 2 是部门 3 和协会 1、2 和 3 的成员,人 3 是部门 1、2 和 4 和协会 3 的成员。我想要的是结果集看起来像
+==========+===============+===============+ |人 |部门 |协会 | +==========+===============+===============+ |人 1 |部门 1 |协会 1 | +------------+--------------+----------------+ |人 1 |部门 2 |空 | +------------+--------------+----------------+ |人 2 |部门 3 |协会 1 | +------------+--------------+----------------+ |人 2 |空 |协会 2 | +------------+--------------+----------------+ |人 2 |空 |协会 3 | +------------+--------------+----------------+ |人 3 |部门 1 |协会 3 | +------------+--------------+----------------+ |人 3 |部门 2 |空 | +------------+--------------+----------------+ |人 3 |部门 4 |空 | +------------+--------------+----------------+我做了什么:
首先我创建了 5 个表:
创建表人员( PersonID int IDENTITY(1,1) NOT NULL, 人名 nvarchar(50) 非空, CONSTRAINT PK_Persons 主键集群(PersonID ASC) ) 创建表关联( AssociationID int IDENTITY(1,1) NOT NULL, AssociationName nvarchar(50) 非空, CONSTRAINT PK_Associations 主键集群(AssociationID ASC) ) 创建表部门( DepartmentID int IDENTITY(1,1) NOT NULL, 部门名称 nvarchar(50) 非空, CONSTRAINT PK_Departments PRIMARY KEY CLUSTERED (DepartmentID ASC) ) 创建表协会成员( PersonID int 非空, AssociationID int 非空, CONSTRAINT PK_AssociationMembers 主键集群(PersonID ASC,AssociationID ASC) ) CREATE TABLE 部门成员( PersonID int 非空, DepartmentID int 非空, CONSTRAINT PK_DepartmentMembers 主键集群(PersonID ASC,DepartmentID ASC) )然后我插入了一些数据:
插入人员(PersonName)值('Person 1') 插入人员(PersonName)值('Person 2') 插入人员(PersonName)值('Person 3') 插入关联(关联名称)值(“关联 1”) 插入关联(关联名称)值(“关联 2”) 插入关联(关联名称)值(“关联 3”) 插入部门(部门名称)值(“部门 1”) 插入部门(部门名称)值(“部门 2”) 插入部门(部门名称)值(“部门 3”) 插入部门(部门名称)值(“部门 4”) 插入 AssociationMembers(PersonID,AssociationID)值 (1, 1) 插入 AssociationMembers(PersonID, AssociationID) 值 (2, 1) 插入 AssociationMembers(PersonID, AssociationID) 值 (2, 2) 插入 AssociationMembers(PersonID, AssociationID) 值 (2, 3) 插入 AssociationMembers(PersonID, AssociationID) 值 (3, 3) 插入部门成员(PersonID、DepartmentID)值 (1, 1) 插入部门成员(PersonID、DepartmentID)值(1、2) 插入部门成员(PersonID,DepartmentID)值(2、3) 插入部门成员(PersonID、DepartmentID)值 (3, 1) 插入部门成员(PersonID、DepartmentID)值 (3, 2) 插入部门成员(PersonID、DepartmentID)值(3、4)并创建了两个视图:
创建视图 v_AssociationMemberships 作为 选择 p.PersonID, ROW_NUMBER() OVER (PARTITION BY p.PersonID ORDER BY a.AssociationID) AS 'AssociationRow', p.人名, a.AssociationID, a.AssociationName 从 dbo.Persons p INNER JOIN dbo.AssociationMembers am ON am.PersonID = p.PersonID INNER JOIN dbo.Associations a ON a.AssociationID = am.AssociationID 创建视图 v_DepartmentMemberships 作为 选择 p.PersonID, ROW_NUMBER() OVER (PARTITION BY p.PersonID ORDER BY d.DepartmentID) AS 'DepartmentRow', p.人名, d.部门ID, d.部门名称 从 dbo.Persons p 内部加入 dbo.DepartmentMembers dm ON dm.PersonID = p.PersonID INNER JOIN dbo.Departments d ON d.DepartmentID = dm.DepartmentID这是最终查询现在的样子,并且 - 它有效,它正在做它应该做的事情,但我想知道是否有更简单、更优雅的方式来做它(使用任何 T-SQL 可能提供的方法):
选择 ISNULL(t.aPersonName, t.dPersonName) 作为人名, t.dDepartmentName AS 部门名称, t.aAssociationName AS 关联名称 从 ( 选择 d.PersonName AS dPersonName, d.DepartmentName AS dDepartmentName, a.PersonName AS aPersonName, a.AssociationName AS aAssociationName 从 dbo.v_DepartmentMemberships d 右外连接 dbo.v_AssociationMemberships a ON a.PersonID = d.PersonID AND a.AssociationRow = d.DepartmentRow 联盟 选择 d.PersonName AS dPersonName, d.DepartmentName AS dDepartmentName, a.PersonName AS aPersonName, a.AssociationName AS aAssociationName 从 dbo.v_AssociationMemberships 一个 右外连接 dbo.v_DepartmentMemberships d ON d.PersonID = a.PersonID AND d.DepartmentRow = a.AssociationRow ) 吨 订购方式 人名, ISNULL(t.dDepartmentName, 'zzzzzzzzzzzzz'), ISNULL(t.aAssociationName, 'zzzzzzzzzzzzz')谢谢 - 也许有人可以为这个问题推荐一个更好的标题。
【问题讨论】:
标签: sql-server tsql