Поиск крошек для вложенных наборов
Я использую вложенные наборы (или измененный обход дерева предзаказа) для хранения списка групп, и я пытаюсь найти быстрый способ создания хлебных крошек (в виде строки, а не таблицы) для ВСЕХ групп одновременно. Мои данные также хранятся с использованием модели списка смежности (есть триггеры для синхронизации двух).
Так, например:
ID Name ParentId Left Right
0 Node A 0 1 12
1 Node B 0 2 5
2 Node C 1 3 4
3 Node D 0 6 11
4 Node E 3 7 8
5 Node F 4 9 9
Который представляет дерево:
Узел АУзел БУзел СУзел ДУзел ЕУзел FЯ хотел бы иметь возможность иметь пользовательскую функцию, которая возвращает таблицу:
ID Breadcrumb
0 Node A
1 Node A > Node B
2 Node A > Node B > Node C
3 Node A > Node D
4 Node A > Node D > Node E
5 Node A > Node D > Node F
Чтобы сделать это немного сложнее (хотя это и выходит за рамки вопроса), у меня также есть ограничения пользователей, которые необходимо соблюдать. Так, например, если у меня есть доступ только к id = 3, при запуске запроса я должен получить:
ID Breadcrumb
3 Node D
4 Node D > Node E
5 Node D > Node F
У меня есть пользовательская функция, которая принимает идентификатор пользователя в качестве параметра и возвращает таблицу с идентификаторами всех групп, которые являются действительными, так долго, как где-то в запросе
WHERE group.id IN (SELECT id FROM dbo.getUserGroups(@userid))
это будет работать.
У меня есть существующая скалярная функция, которая может сделать это, но она просто не работает с любым разумным количеством групп (занимает более 10 секунд на 2000 групп). Он принимает groupid и userid в качестве параметра и возвращает nvarchar. Он находит родителей заданных групп (1 запрос для захвата левого / правого значений, другой - для поиска родителей), ограничивает список группами, к которым у пользователя есть доступ (с использованием того же предложения WHERE, что и выше, поэтому еще один запрос), и затем использует курсор, чтобы пройти каждую группу и добавить ее в строку, прежде чем, наконец, вернуть это значение.
Мне нужен метод для этого, который будет работать быстро (например, <= 1 с) на лету.
Это на SQL Server 2005.