如何从oracle的层次结构中查询

时间:2012-05-26 19:46:29

标签: sql oracle hierarchy

我使用的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

客户可以通过其定义的客户群或作为链的成员专门(基于帐号)进行广告活动。

我使用此查询查找对给定客户有效的所有广告系列:

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 Spinach Empire”是连锁店“菠菜经销商公司”的成员,后者又是更大的“GreenFud R US”连锁店的一部分,后者又是其中的一部分。连锁“FoAC”。当有针对“GreenFud R US”的广告系列时,大力水手有资格参加该广告系列。我的查询只会返回专门添加大力水手的广告系列,或者针对“菠菜经销商公司”的广告系列。

如何修改我的查询以包含客户间接参与的广告系列?

1 个答案:

答案 0 :(得分: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
        )