#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть фрейм данных с идентификатором сотрудника, идентификатором менеджера и электронной почтой менеджера, и доступны электронные письма нескольких конкретных менеджеров, которые я хочу оценить.
До сих пор мне удалось подсчитать совокупное количество прямых и косвенных отчетов, однако я не могу найти способ сгруппировать по начальному линейному менеджеру и получить общее количество прямых и косвенных отчетов для каждого из них.
Примерные данные:
идентификатор сотрудника | идентификатор сотрудника менеджера | электронная почта линейного менеджера | Эл. адрес |
---|---|---|---|
234567 | 3456 | marco.dull@email.com | ann@email.com |
699999 | 234567 | ann@email.com | smith@email.com |
33333 | 3456 | marco.dull@email.com | julian@email.com |
666666 | 234567 | ann@email.com | john@email.com** |
Выходной сигнал:
менеджер | прямые отчеты | косвенные отчеты |
---|---|---|
marco.dull@email.com | 2 | 2 |
Это мой код до сих пор:
select 0 as match_found,*
into #data
from clean.allemployees a
where a.reportingdate='31 oct 2020'
update d set d.match_found=1
from #data d
where d.EmailAddress in ('email1@goog.com', 'email2@goog.com', 'email3@goog.com')
update d set d.match_found=1
from #data d
where d.LineManager_EmployeeID in (
select d.EmployeeID
from #data d
where d.match_found=1
)
select *
from #data d
where d.LineManager_EmployeeID in (
select d.EmployeeID
from #data d
where d.match_found=1
)
select count(distinct JobTitle)
from #data d
where d.LineManager_EmployeeID in (
select d.EmployeeID
from #data d
where d.match_found=1
)
Есть какие-нибудь предложения?
Комментарии:
1. пожалуйста, предоставьте примерные данные и желаемый результат
2. этого достаточно? Спасибо
Ответ №1:
если у вас есть только 1 уровень косвенного менеджера, вы просто можете использовать join и group примерно так:
DROP TABLE IF EXISTS #employees;
CREATE TABLE #employees
(
employeeid INT
, manageremployeeid INT
, linemanageremail VARCHAR(100)
, emailaddress VARCHAR(100)
);
INSERT into #employees values
(234567 ,3456 ,'marco.dull@email.com','ann@email.com' )
,(699999 ,234567 ,'ann@email.com','smith@email.com' )
,(33333 ,3456 ,'marco.dull@email.com','julian@email.com' )
,(666666 ,234567 ,'ann@email.com','john@email.com' )
SELECT e.linemanageremail
, COUNT(DISTINCT e.employeeid) [direct manger]
, COUNT(CASE WHEN mgr.employeeid IS NOT NULL THEN 1 END) AS [indirect manger]
FROM #employees AS e
LEFT JOIN #employees mgr
ON e.emailaddress = mgr.linemanageremail
GROUP BY e.linemanageremail
но если вы считаете косвенных менеджеров на более глубоких уровнях и считаете независимых менеджеров уровня 1, уровня 2 и т. Д., Вам Нужно использовать рекурсивный cte и pivot, однако вам нужно знать, насколько высокий уровень
; WITH cte AS (
SELECT * ,0 level
FROM #employees AS e
UNION ALL
SELECT e.* , level 1 AS level FROM cte
JOIN #employees AS e
ON cte.manageremployeeid = e.employeeid
)
SELECT * FROM
(
SELECT cte.linemanageremail ,cte.level , COUNT(*) AS mgrc
FROM cte
GROUP BY cte.linemanageremail ,cte.level
) AS source
PIVOT (
sum(mgrc)
FOR level IN ([0], [1])
)AS pt;
если у вас есть более глубокие косвенные менеджеры, но вы все равно хотите подсчитать их в группе ‘indiredt manager’, вы можете изменить приведенный выше запрос на этот:
; WITH cte AS (
SELECT * ,'direct ' level
FROM #employees AS e
UNION ALL
SELECT e.* , 'indirect' level
FROM cte
JOIN #employees AS e
ON cte.manageremployeeid = e.employeeid
)
SELECT * FROM
(
SELECT cte.linemanageremail ,cte.level , COUNT(*) AS mgrc
FROM cte
GROUP BY cte.linemanageremail ,cte.level
) AS source
PIVOT (
sum(mgrc)
FOR level IN ([direct], [indirect])
)AS pt;