2012-05-26 2 views
3

Я работаю с базой данных Oracle, которая имеет таблицы для клиентов, цепей и кампаний. Как и (урезанный):Как выполнить запрос из иерархии в oracle

TABLE CUSTOMER 
    ACCOUNTNUMBER VARCHAR2 
    CHAIN   VARCHAR2 
    CATEGORY  VARCHAR2 

TABLE CHAIN 
    CODE   VARCHAR2 
    PARENTCHAIN  VARCHAR2 

TABLE CAMPAIGN 
    ID    NUMBER 
    DISCOUNT  NUMBER 

TABLE CAMPAIGN_ELIGIBILITY 
    CAMPAIGNID  NUMBER --ID of the campaign 
    ACCOUNTNUMBER VARCHAR2 --Customer included in the campaign 
    CHAINCODE  VARCHAR2 --Chain included in the campaign 
    CUSTCATCODE  VARCHAR2 --Customercategory included in the campaign 

Клиент может иметь право на кампанию конкретно (на основе ACCOUNTNUMBER), через его определенную customergroup или в качестве члена цепи.

Я использую этот запрос, чтобы найти все кампании, которые действительны для данного клиента:

select * from campaign where id in 
(
    select unique campaignid from campaign_eligibility where 
    accountnumber=:accountnumber 
    union 
    select unique campaignid from campaign_eligibility where 
    chaincode = 
     (select chain from debtable where accountnumber=:accountnumber) 
    union 
    select unique campaignid from campaign_eligibility where 
    custcatcode = 
     (select category from customer where accountnumber=:accountnumber) 
) 

Теперь, давайте скажем, что клиент «Popeye шпинат Empire» является членом сети «Шпинат дилеров Inc. », который, в свою очередь, является частью более крупной сети« GreenFud R US », которая, в свою очередь, является частью сети« FoAC ». Когда есть кампания, нацеленная на «GreenFud R US», Popeye имеет право на эту кампанию. Мой запрос будет возвращать только кампании, в которых Popeye был специально добавлен, или цели «Spinach Dealers Inc.»,

Как я могу изменить свой запрос, чтобы включить кампании, в которые клиент косвенно входит?

ответ

3
WITH chains AS 
     (
     SELECT code 
     FROM chain c 
     START WITH 
       c.code IN 
       (
       SELECT chain 
       FROM campaign_eligibility 
       WHERE accountnumber = :acc 
       UNION ALL 
       SELECT chain 
       FROM customer c 
       JOIN campaign_eligibility ce 
       ON  ce.custcatcode = c.category 
       WHERE accountnumber = :acc 
       UNION ALL 
       SELECT chain 
       FROM customer 
       WHERE accountnumber = :acc 
       ) 
     CONNECT BY 
       c.code = PRIOR c.parentchain 
     ) ch 
SELECT * 
FROM campaign 
WHERE c.id IN 
     (
     SELECT campaignid 
     FROM chains 
     JOIN campaign_eligibility ce 
     ON  ce.chaincode = c.code 
     ) 
Смежные вопросы