如何使用CTE根据层次结构

时间:2016-06-22 23:04:17

标签: sql common-table-expression

假设我有一个Customer表,其中包含CustomerId作为主键,ParentCustomerId作为外键,我想级联一个insert语句为每个创建一个记录层级链中的客户。

我还有一个CustomerContact表,其主群集主键为CustomerIdPersonIdDateCreated

所以,如果我有以下内容:

客户1:CustomerId: 1ParentCustomerId: Null

客户2:CustomerId: 2ParentCustomerId: 1

客户3:CustomerId: 3ParentCustomerId: 2

我将1传递给我的客户ID,但我想创建3(虽然在这种情况下3是一个变量,层次结构可能会更深),所以我插入一个不同的表链中的每个客户。

declare @1 as int      --customerId
declare @2 as int      --personId for the contact
declare @3 as datetime --DateCreated 

set @1 = 1
set @2 = 1 --personId
set @3 = GetDate()

--I don't know how to use a CTE to get all the CustomerIds that are 
--
--something like 
--with cte_customers
--as
--(select CustomerId from customer
--  where ParentCustomerId = @1
--)

insert into CustomerContact
Values(@1, @2, @3)

如何编写CTE以获取与参数@1相关的所有客户的子项,并为每个客户创建CustomerContact的记录?

1 个答案:

答案 0 :(得分:2)

您需要使用recursive common table expression union all。这是一个简化的例子:

with cte as (
    select customerid, parentcustomerid
    from customer 
    where customerid = 1
    union all 
    select c.customerid, cte.customerid
    from customer c join cte on cte.customerid = c.parentcustomerid)

 insert into customercontact
 select customerId, @1, @2 from cte

使用您的样本数据,这将返回3条记录,并且还可以处理更深层次的关系。