Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Преобразование дерева в строку  [new]
rector
Member

Откуда: Киев
Сообщений: 57
Здравствуйте.
Завис, не могу сделать запрос. Т.е. сделал, но костыль.

Есть таблица сотрудников типа

	
	CREATE TABLE #Users (
		id INT IDENTITY,
		Username VARCHAR (50),
		ManagerId INT 	
	)
	
	INSERT INTO #Users (Username,ManagerId)
	SELECT 'Vasya', NULL
	UNION ALL
	SELECT 'Petya', 1
	UNION ALL
	SELECT 'Kostya',2
	UNION ALL
	SELECT 'Nina',3
	UNION ALL
	SELECT 'Fedya',4
	UNION ALL
	SELECT 'Igor', 5
	UNION ALL
	SELECT 'Katya',5


красивое такое себе дерево.

Надо получить
idUserLoginDirectorLoginDepartmentLoginUnitHeadTeamHead
1VasyaNULLNULLNULLNULL
2PetyaVasyaVasyaVasyaVasya
3KostyaPetyaPetyaPetyaPetya
4NinaKostyaKostyaKostyaKostya
5FedyaNinaNinaNinaNina
6IgorPetyaKostyaNinaFedya
7KatyaPetyaKostyaNinaFedya



т.е. разворачиваем таблицу + если человек сам является руководителем, например он UnitHead, то в колонке TeamHead у него должен быть DepartmentLogin, т.е. менеджер верхнего уровня.

Понятное дело, что количество строк не известно.
Id типа identity только для теста, в таблице с реальными данные Id импортируется из другой программы.

сейчас сделал так (сам знаю, что ужОс, но ничего лучшего в голову не приходит):

	WITH cte AS (
		SELECT *, 0 as level FROM #Users
		WHERE #Users.ManagerId	IS NULL
		
		UNION ALL
		
		SELECT u.*, LEVEL +1 FROM #Users u
		JOIN cte c ON u.ManagerId=c.id
	
	)
	
	
SELECT distinct 
	c.id,
    c.UserName AS UserLogin,
    CASE
	WHEN c2.Level < 4 THEN  c2.Username
	ELSE c5.UserName
end	AS DirectorLogin,
CASE
	WHEN c2.Level < 4 THEN  c2.Username
	ELSE c4.UserName
END AS DepartmentLogin,
CASE
	WHEN c2.Level < 4 THEN  c2.Username
	ELSE c3.UserName
END AS UnitHead,
c2.Username AS TeamHead 		
FROM cte c
LEFT JOIN cte c2 ON c.managerid=c2.id
LEFT JOIN cte c3 ON c2.managerid=c3.id
LEFT JOIN cte c4 ON c3.managerid=c4.id
LEFT JOIN cte c5 ON c4.managerid=c5.id


Понятное дело, что тормозит жутко.
Кто может подсказать, как сделать правильно ?
4 сен 12, 19:33    [13113826]     Ответить | Цитировать Сообщить модератору
 Re: Преобразование дерева в строку  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
rector,

логика запроса непонятна, зачем было городить CTE - тоже непонятно, но вот такой запрос вроде бы даёт такой же результат:
select a.id,a.Username,
  case when e.ManagerId is null then b.Username else e.Username end as DirectorLogin,
  case when e.ManagerId is null then b.Username else d.Username end as DepartmentLogin,
  case when e.ManagerId is null then b.Username else c.Username end as UnitHead,
  b.Username as TeamHead
from #Users a
  left join #Users b on b.id=a.ManagerId
  left join #Users c on c.id=b.ManagerId
  left join #Users d on d.id=c.ManagerId
  left join #Users e on e.id=d.ManagerId

А ещё можно (нужно) добавить PRIMARY KEY по id, должно стать быстрее.
4 сен 12, 21:40    [13114255]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить