2017-06-09 62 views
-1

在我的SQL数据模型中,我有一个将客户与客户帐户关联的关系表。一个账户可以由多个客户持有,而一个客户可以持有多个账户。SQL中的递归CTE - 如何避免重复结果?

我想找到客户之间的关系,同时也显示帐户。为此,我创建了一个给定客户编号的CTE,递归提取客户关系和关系的关系。

例如,假设我有以下数据集:

  • 顾客1,帐户1
  • 顾客2,帐户1
  • 顾客2,账户2
  • 客户3,帐户2
  • 客户4,账户3

运行CTE for客户编号1我想获取客户1,2,3,帐户1,2。但是,因为这是递归的,我也提取每个重复的关系(1 - > 2 - > 1),直到预设的最大深度。有什么办法可以“标记”现有的关系,因此不会重复选择?

这里是我的CTE,以关闭微软的CTE例如:

WITH EntityRelations(CUSTOMERNUMBER, ACCOUNTID, RELATEDWITH, Level) 
AS 
(
    SELECT 
     C.CUSTOMERNUMBER, 
     A.ACCOUNTNUMBER, 
     CREL.CUSTOMER related, 
     0 as level 
    FROM CUSTOMER_ACCOUNT CA 
    INNER JOIN CUSTOMER C 
     ON C.ID = CA.CUSTOMERID 
    INNER JOIN ACCOUNT A 
     ON A.ID = CA.ACCOUNTID 
    --Get direct relationships 
    LEFT JOIN CUSTOMER_ACCOUNT CREL 
     ON CREL.ACCOUNTID = CA.ACCOUNTID 
     AND CREL.CUSTOMERID <> CA.CUSTOMERID 
    WHERE BCE.CUSTOMER = 1 

    UNION ALL 
    --Recursion 
    SELECT 
     C.CUSTOMERNUMBER, 
     A.ID, 
     CREL.CUSTOMER related, 
     Level+1 
    FROM CUSTOMER_ACCOUNT CA 
    INNER JOIN CUSTOMER C 
     ON C.ID = CA.CUSTOMERID 
    INNER JOIN ACCOUNT A 
     ON A.ID = CA.ACCOUNTID 
    --Get direct relationships 
    LEFT JOIN CUSTOMER_ACCOUNT CREL 
     ON CREL.ACCOUNTID = CA.ACCOUNTID 
     AND CREL.CUSTOMERID <> CA.CUSTOMERID 
    INNER JOIN EntityRelations ER 
     ON ER.RELATEDWITH = CA.CUSTOMERID 
    WHERE Level < 3 --Maximum 
) 

SELECT * FROM EntityRelations 
+0

您可以在[本答案](https://stackoverflow.com/a/22453893/243373)和[本答案](https://stackoverflow.com/a/11042012/243373)中找到一个很好的方法。 –

+1

[TSQL CTE:如何避免循环遍历?](https:// stackoverfl ow.com/questions/11041797/tsql-cte-how-to-avoid-circular-traversal) –

回答

0

在你SELECT保持客户的CSV列表,然后检查是否有新客户是企业的名单还是不上。

的想法基本伪代码

SELECT .... , ',' as lstCustomer -- empty list 

UNION ALL 

SELECT .... , customerID || ',' as lstCustomer -- add new customer 

WHERE ',' || lstCustomer || ',' 
     NOT LIKE '%,' || customerID || ',%' 
         -- Check if list already have this customer 

编辑:我是假设你想限制的数量出现CUSTOMER,如果你想限制Customer, Account你做这样的事情

UNION ALL 

SELECT .... , '{' || customerID || '-' || accountID || '},' as lstCustomer 
       -- add new customer 

WHERE ',' || lstCustomer || ',' 
     NOT LIKE '%,{' || customerID || '-' || accountID || '},%' 
         -- Check if list already have this customer