2017-06-09 14 views
-1

私のSQLデータモデルでは、顧客と顧客アカウントを結ぶ関係テーブルがあります。アカウントは複数の顧客によって保持され、顧客は複数のアカウントを保持することができます。SQLの再帰CTE - 繰り返し結果を避けるにはどうすればよいですか?

アカウントを表示しながら、顧客間の関係を見つけたいと思っています。これに私はカスタムナンバーを与えられたCTEを作成し、その顧客の関係と関係の関係を再帰的に取り出します。 、顧客3 2

  • 、顧客2 1
  • 、顧客2 1
    • 顧客1 2
    • アカウントアカウントのアカウントのアカウント:例えば

      、私は、次のデータセットを持っていると仮定

    • 顧客4、アカウント3

    顧客番号1私は顧客1,2,3およびアカウント1,2をフェッチしたい。しかし、これは再帰的なものなので、あらかじめ設定された最大深度まですべての繰り返し関係(1 - > 2 - > 1)も取得している。既存の関係に「フラグを立てて」選択できるようにする方法はありますか?ここで

    は、MicrosoftのCTE例のオフに基づいて、私のCTEである:あなたのSELECT

    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

    新しいお客様がリストにであるかどうかをチェック、顧客の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, Accountの制限をしたい場合は、この

    UNION ALL 
    
    SELECT .... , '{' || customerID || '-' || accountID || '},' as lstCustomer 
           -- add new customer 
    
    WHERE ',' || lstCustomer || ',' 
         NOT LIKE '%,{' || customerID || '-' || accountID || '},%' 
             -- Check if list already have this customer 
    
    ような何かを、 CUSTOMERのために表示される数のためにあなたの希望の限界を想定しました
    関連する問題