У меня небольшая проблема с тем, что SQL Server возвращает те же результаты, что и Oracle для нашего запроса дерева SQL.
У нас есть таблица ссылок с атрибутами
CHILD_ID, LINK_ID, PARENT_ID
и таблица элементов с ELEMENT_ID
В Oracle мы используем это
SELECT * FROM LINKS
JOIN ELEMENTS ON ELEMENT_ID = CHILD_ID
WHERE LINK_ID IN
(SELECT LINK_ID FROM LINKS CONNECT BY PRIOR CHILD_ID = PARENT_ID START WITH PARENT_ID = 'startid')
В SQL Server мы используем это
WITH TREE_LINKS AS
(SELECT CHILD_ID, LINK_ID FROM LINKS WHERE PARENT_ID = 'startid'
UNION ALL
SELECT CURRENT_LINKS.CHILD_ID, CURRENT_LINKS.LINK_ID
FROM LINKS CURRENT_LINKS
INNER JOIN TREE_LINKS t1 ON CURRENT_LINKS.PARENT_ID = t1.CHILD_ID)
SELECT * FROM TREE_LINKS
INNER JOIN LINKS ON TREE_LINKS.LINK_ID = LINKS.LINK_ID
INNER JOIN ELEMENTS ON ELEMENTS.ELEMENT_ID = TREE_LINKS.CHILD_ID
Это прекрасно работает, кроме 1 выпуска.
В Oracle мы получаем только каждую уникальную ссылку, основанную на LINK_ID
. В SQL Server мы получаем все ссылки, описывающие полное дерево, которое может включать дубликаты, когда 1 элемент существует ниже множества других элементов в разных ветвях структуры.
Это означает, что мы получаем большое количество дублирующихся строк из SQL Server. Я тестировал добавление
SELECT DISTINCT TREE_LINKS.LINK_ID AS TREE_LINK_ID, * from TREE_LINKS
в последнем операторе выбора, но это займет столько времени, сколько у сервера есть больше работы по удалению дубликатов, если они найдены в разных ветвях.
В 1 тестовом примере на данный момент Oracle возвращает 20 000 строк, а SQL Server возвращает 1,6 миллиона строк. До сих пор я не нашел способа заставить SQL Server возвращать те же результаты, что и быстро.
К вашему сведению: добавление DISTINCT в причины рекурсии
Оператор DISTINCT недопустим в рекурсивной части рекурсивного
общее табличное выражение 'TREE_LINKS'.
Редактировать: - Пример
Если у нас есть такие ссылки
PARENT_ID, LINK_ID, CHILD_ID
1 1 2
2 2 3
3 3 4
1 4 3
Есть 4 уникальных элемента, но в полном дереве 6 элементов. Это потому, что есть 2 пути к элементу 3