SQL Несколько проверок между двумя таблицами и их хранение - PullRequest
0 голосов
/ 24 ноября 2011

Я использую C # ASP.NET в Visual Studio 2005, а также SQL Server 2005.

В настоящее время у меня есть проект, который требует, чтобы я проверял каждого пользователя на наличие конфликтующих ролей, которыми он может обладать.

У меня есть 2 базы данных. Users и ConflictingRoles. Ниже приведена структура 2 таблиц:

enter image description hereenter image description here

В Users у меня есть 2 уникальных пользователя с 4 ролями в каждом.

В ConflictingRoles у меня 4 ряда конфликтующих ролей.

Джеймс и Дженнифер имеют по 4 роли, и каждая из них конфликтует друг с другом.

Я хочу сформировать несколько SQL-запросов, чтобы проверить каждую роль каждого пользователя, если они конфликтуют с любой другой ролью, которой он обладает.

У меня есть приблизительное представление о том, как будет происходить процесс, но я не уверен, как изобразить идею, используя несколько запросов SQL:


1) По одной строке за раз, grep значение usr. UserID и usr. Role из Users usr стол.

Сохраните usr. UserID во временной переменной tempUID и найдите подходящие значения usr. Role с ср. Role in ConflictingRoles cf table.

2) Если usr. Role соответствует ср. Role, grep значение ср. ConflictingRole и выполнить все usr. Role in Users table WHERE usr. UserID соответствует tempUID.

Если найдено совпадение / конфликт между ср. ConflictingRole с usr. Role пользователя tempUID, введите ср. ConflictingRole, usr. Role и user. Name в отдельную таблицу, Результаты .

3) Повторите это для всех ролей, которыми обладает каждый пользователь, и для всех пользователей.


По сути, пользователь не может играть обе роли, которые конфликтуют друг с другом. Если это так, сохраните имя, роль и конфликтующую роль в таблице.


Это очень смущает меня, и я не уверен, есть ли более простой способ сделать это.

Если нет, я бы хотел попросить вас, ребята, помочь с SQL-запросами, которые мне нужно будет сформировать с помощью приведенной выше логической последовательности.

SqlConnection thisConnection = new SqlConnection("Data Source=DS");
SqlCommand nonqueryCommand = thisConnection.CreateCommand();
thisConnection.Open();

      //multiple sql commands
      nonqueryCommand.CommandText = "<SQL Query>";
      Console.WriteLine(nonqueryCommand.ExecuteNonQuery());

      ...

Спасибо за любую помощь заранее.

Ответы [ 3 ]

1 голос
/ 24 ноября 2011

Первый подход:

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
        )
1 голос
/ 24 ноября 2011
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)
0 голосов
/ 24 ноября 2011

Обратите внимание, что ваша таблица Users не полностью нормализована.Предложение: сведения о пользователях (UserId, Name) должны быть в таблице «сущностей», а отношения между пользователем и их ролями должны быть в отдельной таблице «отношений».

Вы не опубликовалиограничения вашей схемы, но могут заключаться в том, что в приведенном ниже коде 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
              );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...