Найти подходящую запись в SQL Server - PullRequest
0 голосов
/ 24 июня 2019

у меня 3 таблицы; enter image description here

1)Employee      (EmployeeId,Name)
2)Role          (RoleId,RoleName)
3)EmployeeRole  (EmployeeId,RoleId)

У меня есть эти записи;

Я хочу сделать это, я дам EmployeeId, и запрос должен дать мне ответ, какие пользователи имеют ту же роль, что и Employee, которую я дал EmployeeID.

Например;

Я даю EmployeeID 1, я хочу видеть, что у сотрудников есть роли 1,2,3 (все они, я не хочу получать 1 или 2 или 1,2 или 1,3, я хочу 1,2,3 все роли должны совпадать)

Как я могу вам помочь?

Я пробовал это, но я не работал, это мой запрос;

DECLARE @Query varchar(max) = ''
DECLARE @RoleID INT
DECLARE crsEmployeeRole CURSOR FOR
SELECT RoleID FROM Employee_Role where EmployeeID = 2340
OPEN crsEmployeeRole
FETCH NEXT FROM crsEmployeeRole INTO @RoleID
WHILE @@FETCH_STATUS = 0
       BEGIN
            SET @Query = @Query + 'select EmployeeID into #temp'+cast(@RoleID as varchar(max))+' from Employee_Role where RoleID = '+cast(@RoleID as varchar(max))+' '
            FETCH NEXT FROM crsEmployeeRole INTO @RoleID
       END
CLOSE crsEmployeeRole
DEALLOCATE crsEmployeeRole

exec(@Query)

DECLARE @Query2 varchar(max) = ''
DECLARE @RoleID2 INT
DECLARE crsEmployeeRole CURSOR FOR
SELECT RoleID FROM Employee_Role where EmployeeID = 2340
OPEN crsEmployeeRole
FETCH NEXT FROM crsEmployeeRole INTO @RoleID2
WHILE @@FETCH_STATUS = 0
       BEGIN
             if(@Query2 = '')
             SET @Query2 = 'SELECT t1.* FROM #temp'+cast(@RoleID2 as varchar(max))+' t1'
             else
             SET @Query2 = @Query2 + ' inner join #temp'+cast(@RoleID2 as varchar(max))+' on t1.EmployeeID = #temp'+cast(@RoleID2 as varchar(max))+'.EmployeeID'
             FETCH NEXT FROM crsEmployeeRole INTO @RoleID2
       END
CLOSE crsEmployeeRole
DEALLOCATE crsEmployeeRole

exec(@Query2)

Ответы [ 4 ]

3 голосов
/ 24 июня 2019

Вы можете посчитать соответствующие роли, используя join и group by:

select employee_id, count(*)
from employee_role er join
     employee_role er1
     on er.role_id = er1.role_id
where er1.employee_id = @id
group by er.employee_id;

A having предложение или подзапрос, а затем делает то, что вы хотите:

select employee_id, count(*)
from employee_role er join
     (select er1.*, count(*) over () as cnt
      from employee_role er1
      where er1.employee_id = @id
     ) er1
     on er.role_id = er1.role_id
group by er.employee_id, cnt
having count(*) = cnt;
2 голосов
/ 24 июня 2019

это будет работать .. GL ...

DECLARE @Query varchar(max) = ''

DECLARE @DeleteTemp varchar(max) = ''

DECLARE @RoleID INT

DECLARE crsEmployeeRole CURSOR FOR

SELECT RoleID FROM Employee_Role where EmployeeID = 1

OPEN crsEmployeeRole

FETCH NEXT FROM crsEmployeeRole INTO @RoleID

WHILE @@FETCH_STATUS = 0

       BEGIN

             SET @DeleteTemp = 'if OBJECT_ID(''tempdb..##temp'+cast(@RoleID as varchar(max))+''') is not null begin DROP TABLE ##temp'+cast(@RoleID as varchar(max))+' end'

             exec (@DeleteTemp)

             SET @Query = @Query + 'select PersonelID into ##temp'+cast(@RoleID as varchar(max))+' from Employee_Role where RoleID = '+cast(@RoleID as varchar(max))+' '      

             FETCH NEXT FROM crsEmployeeRole INTO @RoleID

       END

CLOSE crsEmployeeRole

DEALLOCATE crsEmployeeRole

exec (@Query)

DECLARE @Query2 varchar(max) = ''

DECLARE @RoleID2 INT

DECLARE crsEmployeeRole CURSOR FOR

SELECT RoleID FROM Employee_Role where EmployeeID = 1

OPEN crsEmployeeRole

FETCH NEXT FROM crsEmployeeRole INTO @RoleID2

WHILE @@FETCH_STATUS = 0

       BEGIN

             if(@Query2 = '')

             SET @Query2 = 'SELECT t1.* FROM ##temp'+cast(@RoleID2 as varchar(max))+' t1'

             else
             SET @Query2 = @Query2 + ' inner join ##temp'+cast(@RoleID2 as varchar(max))+' on t1.PersonelID = ##temp'+cast(@RoleID2 as varchar(max))+'.PersonelID'

             FETCH NEXT FROM crsEmployeeRole INTO @RoleID2

       END

CLOSE crsEmployeeRole

DEALLOCATE crsEmployeeRole

exec(@Query2)
0 голосов
/ 24 июня 2019

Вы можете попробовать это:

CREATE TABLE #EMPLOYEE
(
  EMPLOYEEID INT NOT NULL
, NAME VARCHAR(100) NOT NULL
)

INSERT INTO #EMPLOYEE VALUES
  (1, 'John')
, (2, 'Lisa')
, (3, 'Emilia')
, (4, 'Jacob')
, (5, 'Henry')

CREATE TABLE #ROLE
(
  ROLEID INT NOT NULL
, ROLENAME VARCHAR(100) NOT NULL
)

INSERT INTO #ROLE VALUES
  (1, 'helper')
, (2, 'viewer')
, (3, 'designer')

CREATE TABLE #EMPLOYEE_ROLE
(
  EMPLOYEEID INT NOT NULL
, ROLEID INT NOT NULL
)

INSERT INTO #EMPLOYEE_ROLE VALUES
  (1, 1)
, (1, 2)
, (1, 3)
, (2, 2)
, (2, 3)
, (3, 1)
, (3, 2)
, (3, 3)
, (4, 1)
, (5, 1)


SELECT #EMPLOYEE.EMPLOYEEID
     , #EMPLOYEE.NAME 
FROM #EMPLOYEE
INNER JOIN #EMPLOYEE_ROLE 
ON #EMPLOYEE.EMPLOYEEID = #EMPLOYEE_ROLE.EMPLOYEEID
  WHERE #EMPLOYEE_ROLE.ROLEID IN
(  
--EMPLOYEE-ROLES
SELECT DISTINCT ER.ROLEID
FROM #EMPLOYEE E
INNER JOIN #EMPLOYEE_ROLE ER
ON E.EMPLOYEEID = ER.EMPLOYEEID
WHERE E.EMPLOYEEID = 5  --HERE IS THE PARAMETER
)
GROUP BY #EMPLOYEE.EMPLOYEEID
       , #EMPLOYEE.NAME 

Если вы поставите 5 в предложении WHERE, у вас будет

3   Emilia
5   Henry
4   Jacob
1   John

Надеюсь, это поможет

0 голосов
/ 24 июня 2019

Если вам нужны только идентификаторы сотрудников, используйте cte:

with cte as (select roleid from employee_role where employeeid = 1)
select employeeid
from employee_role
where roleid in (select roleid from cte) and employeeid <> 1
group by employeeid
having count(*) = (select count(*) from cte)

Если вы также хотите, чтобы имена сотрудников добавили приведенный выше запрос к таблице employee:

with cte as (select roleid from employee_role where employeeid = 1)
select e.*
from employee e inner join (
    select employeeid
    from employee_role
    where roleid in (select roleid from cte) and employeeid <> 1
    group by employeeid
    having count(*) = (select count(*) from cte)
) g on g.employeeid = e.employeeid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...