Цикл без курсора в SQL Server 2005 - PullRequest
2 голосов
/ 27 мая 2009

У меня есть таблица OrganisationStructure, подобная этой:

OrganisationID INT
ParentOrganisationID INT
OrganisationName VARCHAR(64)

1 | 0 | Company
2 | 1 | IT DIVISION 
3 | 2 | IT SYSTEM BUSINESS UNIT
4 | 1 | MARKETING DIVISION
5 | 4 | DONATION BUSINESS UNIT

Я хочу получить запрос, который, если приложение передает, скажем, OrganisatinID = 1, означает, что оно будет проходить (просматривая родительский / дочерний элемент) до конца этой таблицы и захватывать все возможные. Возвращено OrganisatioIDs = (1, 2, 3, 4, 5).

Другое, если передано OrganisationID = 2, то Возвращено OrganisationID = (2, 3)

Другое, если передано OrganisationID = 3, то Возвращено OrganisationID = 3

Есть идеи сделать это без курсора?

Спасибо

Ответы [ 6 ]

2 голосов
/ 27 мая 2009
declare @rootID int;
select @rootID = 4;
with cte_anchor as (
    SELECT OrganisationID
        , ParentOrganisationID
        , OrganisationName
    FROM Organisation
    WHERE OrganisationID = @rootID)
, cte_recursive as (
    SELECT OrganisationID
        , ParentOrganisationID
        , OrganisationName
    FROM cte_anchor
    UNION ALL
    SELECT o.OrganisationID
        , o.ParentOrganisationID
        , o.OrganisationName
    FROM Organisation o JOIN cte_recursive r
        ON o.ParentOrganisationID = r.OrganisationID)
SELECT * FROM cte_recursive
2 голосов
/ 27 мая 2009

Вы можете использовать CTE SQL 2005, чтобы заставить механизм SQL делать это рекурсивно.

Перечень основных подходов на http://blogs.msdn.com/anthonybloesch/archive/2006/02/15/Hierarchies-in-SQL-Server-2005.aspx

У Celko также есть деревья в книге SQL, которая охватывает все это до n-й степени.

Или вы можете просто перебрать его, выбрав каждый уровень в локальной табличной переменной, а затем зацикливая, вставляя дочерние элементы с выбором, пока ваш @@ ROWCOUNT не станет равным нулю (то есть вы не найдете больше дочерних элементов). Если у вас нет большого количества данных, это легко кодировать, но вы намекнули, что ищете производительность, сказав, что вам не нужен курсор.

1 голос
/ 27 мая 2009

Я полагаю, что на вопрос дан достаточно хороший ответ, однако, если вы заинтересованы в альтернативных методах структурирования ваших данных для лучшего эффекта, поищите в Google «эволюционные способы работы с иерархическими данными». Мне пока не разрешено публиковать ссылки:)

1 голос
/ 27 мая 2009

Попробуйте это для 3 уровней, используя простую грубую грубую силу - вы можете добавлять уровни по мере необходимости.

SELECT DISTINCT OrganizationID  
FROM  
(  
    SELECT
    ParentOrganizationID  
    FROM OrganizationStructure  
    WHERE ParentOrganizationID = @arg  
    UNION ALL  

    SELECT  
    OrganizationID  
    FROM OrganizationStructure  
    WHERE ParentOrganizationID = @arg  

    UNION ALL

    SELECT os2.OrganizationID  
    FROM OrganizationStructure os  
    JOIN OrganizationStructure os2 ON os.OrganizationID = is2.ParentOrganizationID  
    WHERE os.ParentOrganizationID = @arg   
) data
1 голос
/ 27 мая 2009

Сколько уровней может пройти ваша родительская дочерняя структура?

Вы можете выполнить самостоятельное объединение в таблице, чтобы выстроить в линию сущности прародителя / родителя / потомка, но это ограничено количеством уровней, которые могут пройти ваши отношения родитель / потомок.

Я знаю, что вы указали SQL 2005, но вы просто знаете, что этот вид древовидной структуры - это именно то, что новый HierarchyID ( Video Here ) в Sql 2008 для.

1 голос
/ 27 мая 2009

В SqlServer 2005 с общими табличными выражениями возможно выполнение рекурсивных запросов. Пример см. В разделе «Рекурсивные общие табличные выражения» в Общие табличные выражения (CTE) в SQL Server 2005 из 4guysfromrolla.

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