2015-09-08 3 views
-1

Этот запрос выполняет свою задачу хорошо. Я изучаю рекурсивный CTE и не занимаюсь этим просто. Мне было интересно, можно ли здесь использовать rCTE? Может кто-нибудь объяснить, почему или почему нет? Это может помочь мне лучше понять концепцию.Можно ли использовать рекурсивный cte в этом случае?

Вот запрос:

;WITH a 
AS (
    SELECT u.user_login, m.user_id, m.mail_list_id 
    FROM users u 
    INNER JOIN mail_list_users m ON u.user_id = m.mail_list_id 

    ) 
SELECT a.user_login AS 'Mailing List', u1.user_login AS 'User Login' 
FROM a 
INNER JOIN users u1 ON a.user_id = u1.user_id 
ORDER BY a.user_login 
+0

Это своего рода трудно сказать, когда вы не объясните, чего вы пытаетесь достичь. – JodyT

+0

@JodyT Извинения. У меня есть две таблицы: A) mail_list_id, в которой есть два столбца, у которых есть идентификаторы. В частности, в отношениях Manager-Employee (каждый идентификатор менеджера имеет несколько идентификаторов Employeed). Таблица B - это таблица пользователей, в которой есть все данные пользователя (например, таблица сотрудников). Цель состоит в том, чтобы получить два столбца: имя менеджера и имя сотрудника. Я в основном хочу таблицу mail_list_id, но вместо идентификаторов мне нужны имена. Надеюсь, это прояснит ситуацию. – Crabster

+0

Обычно вы использовали бы рекурсивный CTE, если бы у вас была несбалансированная иерархия сотрудников для менеджеров. Например, если у вас был сотрудник с прямой ссылкой на менеджера в сочетании с другим сотрудником, у которого была ссылка на руководителя группы, у которого, в свою очередь, была ссылка на менеджера. Вы должны использовать рекурсивный CTE для работы «вверх по цепочке», пока не найдете фактического менеджера, т. Е. Сгладить отношения с сотрудником/менеджером. Похоже, что ваши данные не соответствуют этому, так как каждый сотрудник уже имеет прямую ссылку на своего менеджера? –

ответ

0

Если текущий запрос работает хорошо, почему вы хотите, чтобы изменить его?

Вы должны сначала подумать, нужно ли рекурсивно получать данные. И тогда, если вам действительно нужен рекурсивный процесс, CTE может быть вариантом, а не наоборот: значение, вы хотите реализовать рекурсивный CTE, нужно ли вам рекурсивно или нет данных.

Рекурсивный CTE может использовать много ресурсов, и его следует использовать только тогда, когда это необходимо, и это лучший вариант.

Пара рекурсивных CTE ниже с образцом emplyee и столом менеджера.

Вы можете использовать рекурсивный CTE, если хотите просмотреть рекурсивно через иерархию таблицы ваших менеджеров и сотрудников.

Если вы wan't знать, кто работает для кого-то такого Бога ниже, на любом уровне иерархии, вы можете использовать такие КТР:

Declare @data table(id int, name varchar(10), manager int) 
insert into @data(id, name, manager) values 
(0, 'God', null) 
, (1, 'John', 0) 
, (2, 'Bob', 1) 
, (3, 'Lisa', 0) 
, (4, 'Jorg', 1) 
, (5, 'Mike', 3) 
, (6, 'Nick', 5); 

with cte(level, id) as (
    Select 0, id From @data Where manager in (Select id From @data Where name = 'God') 
    Union All 
    Select level+1, d.id From @data d 
    Inner Join cte c on c.id = d.manager 
) 
Select c.level, d.name, manager = m.name 
From cte c 
Inner Join @data d on d.id = c.id 
Inner Join @data m on d.manager = m.id 
Order by level 

выход:

level name manager 
0  John God 
0  Lisa God 
1  Mike Lisa 
1  Bob John 
1  Jorg John 
2  Nick Mike 

Здесь уровень означает, что существует менеджер N между name и God.

Если вы wan't подсчитать, сколько сотрудников работают для каждого сотрудника, вы должны использовать рекурсивный КТР, как этот:

with cte(level, id, manager) as (
    Select 0, id, id From @data 
    Union All 
    Select level+1, c.id, d.id From @data d 
    Inner Join cte c on c.manager = d.manager 
) 
Select d.name, employees = count(*)-1 
From cte c 
Inner Join @data d on d.id = c.id 
Group By d.name 
OPTION(MAXRECURSION 0) 

Выход:

name employees 
Bob  0 
God  6 
John 2 
Jorg 0 
Lisa 2 
Mike 1 
Nick 0 
Смежные вопросы