Как использовать рекурсивный запрос в качестве подзапроса? - PullRequest
4 голосов
/ 18 апреля 2011

Мне нужно написать запрос, который многократно вызывает рекурсивный запрос.

Я не смог понять, как это сделать. Я думаю, что я могу сделать это с помощью курсора, подготовив оператор SQL во время выполнения, а затем использовать EXEC (mySQLstatement), чтобы запустить его на каждом курсоре FETCH NEXT.

Во всяком случае, это не очень хороший подход.

Это проблема (конечно, здесь она упрощена, и я оставляю только необходимые столбцы, чтобы выразить себя): У меня есть дерево клиентов (иерархия), и для каждого клиента определены определенные контакты.

Таблица CUSTOMERS содержит поле ID_CUSTOMER и поле ID_PARENT_CUSTOMER таблица CUSTOMER_CONTACTS содержит поле ID_CUSTOMER и поле ID_CONTACT.

С помощью этого запроса (он работает) я могу получить все контакты для клиента 308 и все контакты для его суб-клиентов:

with [CTE] as (
    select ID_CUSTOMER from CUSTOMERS c where c.ID_CUSTOMER = 308
    union all
    select c.ID_CUSTOMER from [CTE] p, CUSTOMERS c 
        where c.ID_PARENT_CUSTOMER = p.ID_CUSTOMER
)
select ID_CUSTOMER into #Customer308AndSubCustomers from [CTE]

select 308 as ParentCustomer, ID_CUSTOMER, ID_CONTACT,  from CUSTOMER_CONTACTS
WHERE ID_CUSTOMER IN (select * from #Customer308AndSubCustomers)
drop table #Customer308AndSubCustomers

Но я хотел бы иметь в одном запросе то же самое для ВСЕХ ЗАКАЗЧИКОВ, а не только для 308. Так вот почему я предложил использовать курсор, чтобы я мог повторно использовать приведенный выше оператор и просто использовать переменную вместо 308.

Но можете ли вы предложить лучший запрос?

1 Ответ

7 голосов
/ 18 апреля 2011

Просто удалите условие фильтрации из якорной части:

WITH    q AS
        (
        SELECT  ID_CUSTOMER, ID_CUSTOMER AS root_customer
        FROM    CUSTOMERS c
        UNION ALL
        SELECT  c.ID_CUSTOMER, q.root_customer
        FROM    q
        JOIN    CUSTOMERS c 
        ON      c.ID_PARENT_CUSTOMER = q.ID_CUSTOMER
        )
SELECT  *
FROM    q

root_customer покажет вам корень цепи.

Обратите внимание, что одни и те же клиенты могут возвращаться несколько раз.

Скажем, внук будет возвращаться как минимум трижды: в дереве деда, в родительском дереве и в своем дереве, но каждый раз с другим root_customer.

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