存储过程sql server正在尝试消除DUP(多对多关系)
这句话有点难存储过程sql server正在尝试消除DUP(多对多关系),sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,这句话有点难 表A有一个角色 表B将角色与资产联系起来 表C是关于资产的 从角色到资产存在多对多关系 基于资产中的列位值。。我想将其映射到具有该值的角色。但由于多对多的关系,我得到了很多角色。因此,我想要的是,如果任何资产的bit=1,则返回等价的角色。我不希望角色的PK重复。我返回重复角色(按PK)的查询如下所示 select rls.Role_ID, asset.Asset_ID, Asset.Is_Public from Roles r
- 表A有一个角色
- 表B将角色与资产联系起来
- 表C是关于资产的
select rls.Role_ID,
asset.Asset_ID,
Asset.Is_Public
from Roles rls
inner join Role_Asset on rls.Role_ID = Role_Asset.Role_ID
inner join Asset on Role_Asset.Asset_ID = asset.Asset_ID
where Asset.Is_Public =1
问题是,由于多对多的关系,我要扮演许多角色。。如果任何公共资产绑定到角色。。我想要那个角色,但只想要那个角色。如果一个角色绑定到多个资产,一个为1,另一个为0。我仍然希望返回它(因此,如果任何公共资产与角色绑定,则返回它)
相反(AKA IS_PUBLIC=0)在WHERE子句中尝试使用EXISTS语句,如下所示:
SELECT rls.Role_ID
FROM Roles rls
WHERE EXISTS (
SELECT 1
FROM Role_Asset ra
WHERE ra.Role_ID = rls.Role_ID
AND EXISTS (
SELECT 1
FROM Asset a
WHERE a.Asset_ID = ra.Asset_ID
AND a.Is_Public = 1
)
);
您正在第三个名为Role_Assets的表中定义两者之间的关系,因此必须创建一个左连接而不是内部连接,因为内部连接将排除不匹配的值。此外,您必须从复合表中选择ROLEID,而不是使用ROLES_表。这样,您将得到所有角色,这些角色都是真实的公共资产。换句话说,您的结果集如下所示:
ROLE ID ASSET ID PUBLIC
1 1 1
1 2 1
1 3 1
2 1 0
2 2 0
你试过按角色进行分组吗?一开始我想可能是这样。如果我更改a.Ispublic=0,我仍然返回连接到公共资产的角色。我应该能翻转那一点,得到相反的结果。然后,联合在一起的两个查询将返回所有角色。这得到了您要求的答案,即“如果任何公共资产绑定到一个角色..我需要该角色,但只需要该角色。如果一个角色绑定到多个资产,一个是1,另一个是0。我仍然希望返回该角色(因此,如果绑定到角色的任何公共资产都将返回该角色)。”我已经用过左外。。我只把它作为内在的,因为它没有什么不同。在您发布的示例中,它应该只返回角色\u ID 1。我得到的结果正是我使用的结果。我不想在以后的代码中对重复的结果进行排序。