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だけでなく、すべての顧客に対して同じクエリを1回実行したいと考えています。これが、上記のステートメントを再利用して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チェーンのルートが表示されます。

同じ顧客が複数回返される場合があることに注意してください。

たとえば、孫は少なくとも 3 回返されます。祖父母ツリー、親ツリー、および独自のツリーで、毎回異なるroot_customer.

于 2011-04-18T13:46:27.820 に答える