4

我需要编写一个多次调用递归查询的查询。

我无法弄清楚该怎么做。我想我可以通过使用游标来做到这一点,在运行时准备 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。

但是你能提出一个更好的查询吗?

4

2 回答 2

9

只需从锚部分中删除过滤条件:

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.

于 2011-04-18T13:46:27.820 回答
0

在 PostgreSQL 中,您可以编写递归查询 CTE,如下所示。下面的查询使用 id(7) 获取给定类别的所有子类别

WITH RECURSIVE category_tree(id, parent_category) AS (
   SELECT id, parent_category
   FROM category
   WHERE id = 7  -- this defines the start of the recursion
   UNION ALL
   SELECT child.id,  child.parent_category
   FROM category   child
     JOIN category_tree  parent ON parent.id = child.parent_category -- the self join to the CTE builds up the recursion
)
SELECT * FROM category_tree;
于 2020-11-19T15:08:37.403 回答