Представление иерархических данных с различными условиями в SQL Server 2014 - PullRequest
1 голос
/ 04 мая 2020

У меня есть две таблицы. В одной таблице мои необработанные данные, а в другой таблице - отношения как показано ниже

Declare @Emp table(EmpId int,EmpName Varchar(100),CITY VARCHAR(100),Designation Varchar(100),ReportingManager Int)
INSERT INTO @Emp
VALUES(1,'Ram','Hyderabad','TL',6)
,(2,'Laxman','Hyderabad','TL',9)
,(3,'Suresh','Bangalore','Officer',6)
,(4,'Rajesh','Bangalore','Officer',9)
,(5,'Lokesh','Delhi','TL',6)
,(6,'Venkatesh','Mumbai','Manager',6)
,(7,'Subbu','Patna','Officer',9)
,(8,'Ravi','Hyderabad','Officer',9)
,(9,'Sai','Hyderabad','Manager',9)
,(10,'Satish','Hyderabad','Officer',6)

DECLARE @EmpRelation TABLE(EmpRelationShipID INT IDENTITY NOT NULL,ReportingTo INT,EmpID INT)
INSERT INTO @EmpRelation
VALUES(1,6)
,(2,9)
,(3,1)
,(4,5)
,(5,6)
,(7,2)
,(8,5)
,(10,1)
  • Здесь столбец ReportingManager в таблице @Emp указывает, что если Emp сообщает TL, то TN's ManagerName
  • Здесь столбец ReportingTo в @EmpRelation указывает, кому он сообщает. (TL или Менеджер)
  • Офицеры отчитываются перед TL, а TL - перед менеджерами.

Мне нужны данные, как показано ниже

[EMPID],[EMPNAME],[CITY],[IsManager],[HasSubordinates],[IsSubordinate],[ManagerCity],[SubordinatesList] 
  • Здесь поле [IsManager] означает, что если Сотрудник является Менеджером, то это «Да», иначе «Нет». В таблице @Emp «Sai» - «Менеджер», поэтому для него это «Да».

  • [HasSubordinates], если у сотрудника есть работающие под ним сотрудники, то «Да» или «Нет». В этом случае для TL и менеджеров этот столбец Да

  • [IsSubordinate] означает, что если сотрудник отчитывается перед кем-либо, тогда это да, в этом случае TL и сотрудники имеют Да

  • [ManagerCity] Предположим, что если сотрудник отчитывается перед TL, то его город менеджеров TL

  • [SubordinatesList] Сотрудники, работающие под TL / Manager. Для офицеров это пусто

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

1 Ответ

2 голосов
/ 04 мая 2020

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

select E.EmpId, E.EmpName, E.City, E.Designation,
  -- Anyone who reports to themselves is a manager.
  case when E.EmpId = E.ReportingManager then 'Yes' else 'No' end as IsManager,
  -- Anyone with a related employee reporting to them has subordinates.
  case when exists ( select 42 from @EmpRelation as iER where iER.ReportingTo = E.EmpId )
    then 'Yes' else 'No' end as HasSubordinates,
  -- Anyone who reports to an employee is a subordinate.  (Should this exclude reporting to themselves?)
  case when exists ( select 42 from @EmpRelation as iER where iER.EmpId = E.EmpId )
    then 'Yes' else 'No' end as IsSubordinate,
  -- The city of the reporting manager, if any.
  ME.City as ManagerCity,
  -- A comma-delimited list of employees who report directly to the current employee.
  --   Modern versions of SQL Server could use   String_Agg .
  Stuff( (
    select ',' + sE.EmpName
      from @Emp as sE inner join @EmpRelation as sER on sER.EmpId = se.EmpId
      where sER.ReportingTo = E.EmpId
      order by sE.EmpName for XML path(''), type).value('.[1]', 'VarChar(max)' ),
    1, 1, '' ) as SubordinatesList
  from @Emp as E left outer join
    @Emp as ME on ME.EmpId = E.ReportingManager;

Спасибо Вы за предоставление пригодных образцов данных.


Согласно комментарию ОП, таблица @EmpRelation немного озадачивает. @EmpRelation имеет (3,1) и (10,1) как (ReportingTo,EmpId). Это не означает, что EmpId 1 - это ReportingTo 3 и 10 (иначе известный как управление матрицами ). Пересмотр запроса с целью изменения отношения требует незначительных изменений в HasSubordinates, IsSubordinate и SubordinateList:

select E.EmpId, E.EmpName, E.City, E.Designation,
  -- Anyone who reports to themselves is a manager.
  case when E.EmpId = E.ReportingManager then 'Yes' else 'No' end as IsManager,
  -- Anyone with a related employee reporting to them has subordinates.
  case when exists ( select 42 from @EmpRelation as iER where iER.EmpId = E.EmpId )
    then 'Yes' else 'No' end as HasSubordinates,
  -- Anyone who reports to an employee is a subordinate.  (Should this exclude reporting to themselves?)
  case when exists ( select 42 from @EmpRelation as iER where iER.ReportingTo = E.EmpId )
    then 'Yes' else 'No' end as IsSubordinate,
  -- The city of the reporting manager, if any.
  ME.City as ManagerCity,
  -- A comma-delimited list of employees who report directly to the current employee.
  --   Modern versions of SQL Server could use   String_Agg .
  Stuff( (
    select ',' + sE.EmpName
      from @Emp as sE inner join @EmpRelation as sER on sER.ReportingTo = se.EmpId
      where sER.EmpId = E.EmpId
      order by sE.EmpName for XML path(''), type).value('.[1]', 'VarChar(max)' ),
    1, 1, '' ) as SubordinatesList
  from @Emp as E left outer join
    @Emp as ME on ME.EmpId = E.ReportingManager;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...