Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как использовать результаты вложенного рекурсивного подзапроса?  [new]
AndrewAtLipetsk
Member

Откуда:
Сообщений: 4
Добрый день, коллеги.
Пока не было рекурсий, было всё просто:
select * from таблица where таблица.id in (select id from таблица where условие)

Всё работало, вложенный запрос возвращал перечень идентификаторов, удовлетворяющих условию отбора, после чего внешний запрос выдавал результат. Я сейчас не об оптимизации приведенного мною запроса - понятно что тут не нужен вложенный запрос в приниципе... Я о самой схеме in.

Теперь с рекурсией, хочется использовать ту же схему. Но она не работает. Отдельно запрос с рекурсией возвращает всё как положено, если же его обвести в скобки, и указать как указано ниже - MS Sql manager studio выдаст ошибку.

select * from Subdivisions where id in ( 
 WITH tree (id , name, idParent) 
 AS ( SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t WHERE t.ID = 1 UNION ALL 
 SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t INNER JOIN tree ON ( t.Id_parent = tree.id )) 
 SELECT tr.id FROM tree tr order by tr.id
 )

текст ошибки
Сообщение 156, уровень 15, состояние 1, строка 3
Incorrect syntax near the keyword 'WITH'.
Сообщение 319, уровень 15, состояние 1, строка 3
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Сообщение 102, уровень 15, состояние 1, строка 7
Incorrect syntax near ')'.


Собственно вопрос -я хочу в рекурсии выбрать все элементы на разных уровнях дерева, удовлетворяющие условию. А в основном запросе, должен выдать только их. (where id in (*) )
Какие тут есть варианты?
18 июл 18, 11:15    [21580319]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результаты вложенного рекурсивного подзапроса?  [new]
Guf
Member

Откуда: Новосибирск
Сообщений: 641
AndrewAtLipetsk,

 WITH tree (id , name, idParent) 
 AS ( SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t WHERE t.ID = 1 UNION ALL 
 SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t INNER JOIN tree ON ( t.Id_parent = tree.id )) 
select * from Subdivisions where id in (SELECT tr.id FROM tree tr order by tr.id)
18 июл 18, 11:17    [21580328]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результаты вложенного рекурсивного подзапроса?  [new]
AndrewAtLipetsk
Member

Откуда:
Сообщений: 4
Спасибо
18 июл 18, 11:21    [21580347]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результаты вложенного рекурсивного подзапроса?  [new]
AndrewAtLipetsk
Member

Откуда:
Сообщений: 4
А как сделать в таком случае 2 рекурсивных подзапроса?

 WITH tree (id , name, idParent) 
 AS ( SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t WHERE t.ID = 1 UNION ALL 
 SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t INNER JOIN tree ON ( t.Id_parent = tree.id )) 

 WITH tree2 (id , name, idParent) 
 AS ( SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t WHERE t.ID = 1 UNION ALL 
 SELECT t.ID, t.NAME, t.Id_parent FROM Subdivisions t INNER JOIN tree2 ON ( t.Id_parent = tree2.id )) 

 SELECT tr.id FROM tree tr order by tr.id


На второй with начинает ругаться...
18 июл 18, 11:30    [21580387]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результаты вложенного рекурсивного подзапроса?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
AndrewAtLipetsk,

а вы принципиало хелп не открываете? Гордость или какие фобии?
18 июл 18, 11:36    [21580412]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать результаты вложенного рекурсивного подзапроса?  [new]
AndrewAtLipetsk
Member

Откуда:
Сообщений: 4
Спасибо что именно в хелп ткнули носом, а не куда то еще :) нашел там, вопрос закрыт.

WITH Sales_CTE (SalesPersonID, TotalSales, SalesYear)  
AS  
-- Define the first CTE query.  
(  
    SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, YEAR(OrderDate) AS SalesYear  
    FROM Sales.SalesOrderHeader  
    WHERE SalesPersonID IS NOT NULL  
       GROUP BY SalesPersonID, YEAR(OrderDate)  

)  
,   -- Use a comma to separate multiple CTE definitions.  

-- Define the second CTE query, which returns sales quota data by year for each sales person.  
Sales_Quota_CTE (BusinessEntityID, SalesQuota, SalesQuotaYear)  
AS  
(  
       SELECT BusinessEntityID, SUM(SalesQuota)AS SalesQuota, YEAR(QuotaDate) AS SalesQuotaYear  
       FROM Sales.SalesPersonQuotaHistory  
       GROUP BY BusinessEntityID, YEAR(QuotaDate)  
)  

-- Define the outer query by referencing columns from both CTEs.  
SELECT SalesPersonID 
18 июл 18, 11:42    [21580438]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить