SQL在2个表之间进行多次检查并存储它们

时间:2011-11-24 08:18:27

标签: c# asp.net sql

我在Visual Studio 2005以及SQL Server 2005上使用C#ASP.NET。

目前我有一个项目要求我检查每个用户是否有他们可能拥有的任何冲突角色。

我有2个数据库。 UsersConflictingRoles。以下是2个表格的结构:

enter image description here enter image description here

Users中,我有2个唯一身份用户,每个用户有4个角色。

ConflictingRoles中,我有4行冲突角色。

James和Jennifer各有4个角色,每个角色互相矛盾。

我希望构建多个SQL查询,以检查每个用户拥有的每个角色是否与他们拥有的任何其他角色发生冲突。

我对该过程的概念有一个大概的了解,但我不确定如何使用多个SQL查询来描述这个想法:


1)一次一行,从用户 grep usr。 UserID usr。 Role strong> usr 表。

usr。 UserID存储到临时变量tempUID中,并使用 usr。 Role的匹配值> cf。 Role ConflictingRoles cf 表中。

2)如果 usr。 Role cf。 Role匹配,则grep cf。 {的值{1}}并浏览用户ConflictingRole usr中的所有 usr。 Role {{1}匹配WHERE

如果 cf。 UserID与用户tempUID usr。 ConflictingRole之间发现匹配/冲突,请插入< em> cf。 Role usr。 tempUID user。 ConflictingRole到一个单独的表中,结果

3)对每个用户拥有的所有角色以及所有用户重复此操作。


基本上是不允许用户拥有彼此冲突的两个角色。如果有,请将名称,角色和冲突列表存储在表格中。


这对我来说非常困惑,我不确定是否有更简单的方法来做到这一点。

如果没有,我想请求你们提供SQL查询的帮助,我将用上面的逻辑顺序形成这些查询。

Role

感谢您提前提供任何帮助。

3 个答案:

答案 0 :(得分:1)

SELECT u1.UserID, MIN(u1.Role) AS Role, MAX(u2.Role) AS ConflictingRole
FROM Users AS u1
JOIN Users AS u2 ON u1.UserID = u2.UserID AND u1.Role <> u2.Role
JOIN ConflictingRoles AS cr ON cr.Role = u1.Role AND cr.ConflictingRole = u2.Role
Group By u1.UserID, MIN(u1.Role), MAX(u2.Role)

答案 1 :(得分:1)

第一种方法:

Insert into results(userID, role, conflictingRole)
Select distinct
     U.UserId, U.role, C.conflictionRole
FROM
     users U 
   inner join  --join role with all conflicted roles
     conflictingRoles C
       on U.role = C.role
WHERE
     --chech if user has conflicted role
     exists (
        select * 
        from Users U2
        where  U2.userId = U.userId and
               U2.role = C.conflictionRole
        )

答案 2 :(得分:0)

请注意,您的Users表未完全规范化。建议:用户详细信息(UserIdName)应位于“实体”表中,用户与其角色之间的关系应位于单独的“关系”表中。

您尚未发布架构的约束,但可能会在下面的代码U1.Role <> U2.Role中将其更改为U1.Role < U2.Role。可能最好咨询您的业务领域专家:

WITH Users 
     AS 
     (
      SELECT * 
        FROM (
              VALUES ('R001', 'James', 'ISP001'), 
                     ('R001', 'James', 'ISP002'), 
                     ('R001', 'James', 'OSF001'), 
                     ('R001', 'James', 'OSF002'), 
                     ('P005', 'Jennifer', 'JEP001'), 
                     ('P005', 'Jennifer', 'JEP002'), 
                     ('P005', 'Jennifer', 'FGA001'), 
                     ('P005', 'Jennifer', 'FGA002'), 
                     ('S055', 'OneDayWhen', 'ISP001'), 
                     ('S055', 'OneDayWhen', 'OSF001'), 
                     ('S055', 'OneDayWhen', 'FGA001')
             ) AS T (UserID, Name, Role)
     ), 
     ConflictingRoles AS 
     (
      SELECT * 
        FROM (
              VALUES ('ISP001', 'ISP002'), 
                     ('OSF001', 'OSF002'), 
                     ('JEP001', 'JEP002'), 
                     ('FGA001', 'FGA002') 
             ) AS T (Role, ConflictingRole)
     ), 
     PotentiallyConflictingRoles
     AS
     (
      SELECT U1.UserID, U1.Role, U2.Role AS PotentiallyConflictingRole
        FROM Users U1
             JOIN Users U2
                ON U1.UserID = U2.UserID
                   AND U1.Role <> U2.Role
     )
SELECT *
  FROM PotentiallyConflictingRoles P1
 WHERE EXISTS (
               SELECT * 
                 FROM ConflictingRoles C1
                WHERE C1.Role = P1.Role
                      AND C1.ConflictingRole = P1.PotentiallyConflictingRole
              );