Справка по рекурсивным запросам - PullRequest
1 голос
/ 29 марта 2010

В моей схеме базы данных есть две таблицы, которые представляют сущность, имеющую отношение «многие ко многим» с собой.

Role  
---------------------
+RoleID 
+Name

RoleHasChildRole
---------------------
+ParentRoleID  
+ChildRoleID  

По сути, мне нужно иметь возможность написать запрос, такой что:

При заданном наборе ролей рекурсивно возвращать уникальный набор всех связанных ролей. Это база данных MSSQL 2008.

EDIT:

Требуется запрос данных образца. Итак, вот:

RoleID    Name
------------------------------------
1         'Admin'
2         'SuperUser'
3         'Lackey'
4         'Editor'
5         'CanEditSomething'
6         'CanDeleteSomething'
7         'CanCreateSomething'
8         'CanViewSomething'

ParentRoleID    ChileRoleID
------------------------------------
1               5
1               6
1               7
1               8
2               4
4               5
4               8

Таким образом, запрос на роль администратора вернет:

'Администратор'
'CanEditSomething'
'CanDeleteSomething'
'CanCreateSomething'
'CanViewSomething'

И запрос SuperUser вернет:

суперпользователя '
'Редактор'
'CanViewSomething'
'CanEditSomething'

Ответы [ 2 ]

3 голосов
/ 29 марта 2010

Довольно распространенное использование CTE:

WITH RecursiveRole AS (
  SELECT RoleID AS RecursiveRoleID
  FROM Role
  WHERE Name = @parameter

  UNION ALL

  SELECT ChildRoleID AS RecursiveRoleID
  FROM RoleHasChildRole
  INNER JOIN RecursiveRole
    ON RoleHasChildRole.ParentRoleID = RecursiveRole.RecursiveRoleID
)
SELECT RoleID, RoleName
FROM RecursiveRole
INNER JOIN Role
  ON RecursiveRoleID = RoleID

Этот только идет вниз дерево ролей. Я оставляю создание одного, которое подходит как упражнение.


РЕДАКТИРОВАТЬ Похоже, вы все равно хотели спуститься с дерева. Этот запрос прекрасно справляется.

Возвращает следующие результаты в ваших тестовых данных:

SET @parameter = 'Admin'
1   Admin
5   CanEditSomething
6   CanDeleteSomething
7   CanCreateSomething
8   CanViewSomething

SET @parameter = 'SuperUser'
2   SuperUser
4   Editor
5   CanEditSomething
8   CanViewSomething
0 голосов
/ 29 марта 2010

Мой QCD (быстрый, дешевый и грязный) пример:

Предположим, что простые отношения между сотрудником и менеджером в организации. У нас будет таблица EmployeeManager, EmpMan, которая имеет 2 столбца EmpID и ManID. Я собираюсь опустить другие детали (индексы, вторичные таблицы с именами сотрудников / контактами и т. Д.) Для простоты

CREATE TABLE [dbo].[EmpMan]( [EmpID] [int] NOT NULL, [ManID] [int] NOT NULL) GO;

   insert into dbo.EmpMan   select 2,1

union select 3,1
union select 4,1 
union select 31,3 
union select 32,2
union select 43,4   `/* 3X report to 3 and 4X report to 4*/`

union select 310,31 
union select 314,31 `/* 31X reports to 31*/`

union  select 56,5 union select 87,8 `/*empID 56 reports to 5 and 87 reports to  8, 5 and 8 do not have managers*/`

Запрос CTE может выполнять рекурсивные запросы:

with Manager AS (

/*initialization query*/

select  EmpID,ManID from EmpMan where ManID=1/* assuming that your VP ID is 1, or it can be the top most person whom you want to query on*/

union all

/*recursive query*/

select E.EmpID,E.ManID from EmpMan E

join Manager M on  E.ManID=M.EmpID)

select * from Manager
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...