具有多个查找的复杂SQL问题

时间:2012-01-20 07:24:05

标签: sql oracle

我有一个复杂的sql需要解决,想法是确定特定CUSTOMER_ID的ADMIN_ID。确定ADMIN_ID的规则如下:

  1. 要确定特定帐户的ADMIN_ID,系统应查询 从下到上的帐户,以及TXT01的第一个帐户不为空 它是父母。

  2. ADMIN_ID仅适用于CUSTOMER E组。

  3. 如果顶级帐户缺少TXT01,则应提供警告消息

  4. 只有CUSTOMER_ID = PAYING_ACCOUNT_ID需要分析

  5. 帐户表

    CUSTOMER_ID       PAYING_ACCOUNT_ID         PARENT_ACCOUNT_ID
    3271516           3271516                   719216
    1819276           1819276                   810546
    719216            719216                    719216
    810546            810546                    810547
    810547            810547                    810547
    999999            111111                    111111
    111111            111111                    111111
    123456            123456                    231
    231               231                       231    
    

    客户表

    CUSTOMER_ID         TXT01
    719216              TOM
    810546              NULL
    810547              JIM
    3271516             NULL
    1819276             NULL
    999999              NULL
    111111              BEN
    123456              NULL
    231                 NULL     
    

    客户群

    CUSTOMER_ID         GROUP
    719216              E
    810546              E
    810547              E
    3271516             E
    1819276             E
    999999              E
    111111              E
    123456              E
    231                 E
    888                 A
    

    输出

    CUSTOMER_ID       PAYING_ACCOUNT_ID        PARENT_ACCOUNT_ID        ADMIN_ID
    3271516           3271516                    719216                  TOM
    1819276           1819276                    810546                  JIM
    719216            719216                     719216                  TOM
    810546            810546                     810547                  JIM
    810547            810547                     810547                  JIM
    111111            111111                     111111                  BEN
    123456            123456                     231                     Warning!!
    231               231                        532                     Warning!!   
    

    DDL

    CREATE TABLE ACCOUNT (CUSTOMER_ID NUMBER(20) NOT NULL,
    PAYING_ACCOUNT_ID NUMBER(20),
    PARENT_ACCOUNT_ID NUMBER(20));
    
    CREATE TABLE CUSTOMER (CUSTOMER_ID NUMBER(20) NOT NULL,
    TXT01 VARCHAR2(20));
    
    CREATE TABLE CUSTOMER_GROUP (CUSTOMER_ID NUMBER(20) NOT NULL,
    GROUP VARCHAR2(20));
    
    INSERT INTO ACCOUNT VALUES (3271516,3271516,719216);
    INSERT INTO ACCOUNT VALUES (1819276,1819276,810546);
    INSERT INTO ACCOUNT VALUES (719216,719216,719216);
    INSERT INTO ACCOUNT VALUES (810546,810546,810547);
    INSERT INTO ACCOUNT VALUES (810547,810547,810547);
    INSERT INTO ACCOUNT VALUES (999999,111111,111111);
    INSERT INTO ACCOUNT VALUES (111111,111111,111111);
    INSERT INTO ACCOUNT VALUES (123456,123456,231);
    INSERT INTO ACCOUNT VALUES (231,231,231);
    INSERT INTO CUSTOMER VALUES (719216,'TOM');
    INSERT INTO CUSTOMER VALUES (810546,NULL);
    INSERT INTO CUSTOMER VALUES (810547,'JIM');
    INSERT INTO CUSTOMER VALUES (3271516,NULL);
    INSERT INTO CUSTOMER VALUES (1819276,NULL);
    INSERT INTO CUSTOMER VALUES (999999,NULL);
    INSERT INTO CUSTOMER VALUES (111111,'BEN');
    INSERT INTO CUSTOMER VALUES (123456,NULL);
    INSERT INTO CUSTOMER VALUES (231,NULL);
    INSERT INTO CUSTOMER_GROUP VALUES (719216,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (810546,E);
    INSERT INTO CUSTOMER_GROUP VALUES (810547,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (3271516,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (1819276,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (999999,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (111111,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (123456,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (231,'E');
    INSERT INTO CUSTOMER_GROUP VALUES (888,'A');    
    

    这是我的代码......仍然在做,但在某些方面陷入困境。欣赏大师在这里可以给我一只手

    WITH myData AS (
    SELECT CUSTOMER_ID, TXT01 FROM CUSTOMER WHERE CUSTOMER_ID IN 
    (SELECT CUSTOMER_ID from CUSTOMER_GROUP WHERE GROUP = 'E')
    )   
    SELECT v.*
    FROM
    (SELECT m.* ,
    CASE WHEN TXT01 IS NOT NULL THEN TXT01
    ELSE ( *STUCK HERE*
    END ADMIN_ID
    FROM myData m) v
    

2 个答案:

答案 0 :(得分:0)

SELECT 
C.CUSTOMER_ID, nvl(a.TXT01, 'warning!')
FROM CUSTOMER c
   JOIN CUSTOMER_GROUP cg ON (cg.customer_id = c.customer_id and cg.group = 'E')
   JOIN ACCOUNT a ON (a.customer_id = c.customer_id)
WHERE c.CUSTOMER_ID = a.PAYING_ACCOUNT_ID

答案 1 :(得分:0)

试试这个

with acc_hierarchy as
 (select level lev, ac.*, connect_by_root(ac.paying_account_id) account_id
    from account ac
  connect by prior ac.parent_account_id = ac.paying_account_id
         and prior ac.paying_account_id <> prior ac.parent_account_id),
acc_customers as
 (select ah.account_id, min(c.txt01) keep(dense_rank first order by ah.lev) admin_id
    from acc_hierarchy ah
    left join (select cus.customer_id, cus.txt01
                from customer cus
                join customer_group cg
                  on cg.customer_id = cus.customer_id
                 and cg."GROUP" = 'E') c
      on c.customer_id = ah.customer_id
   where c.txt01 is not null
   group by ah.account_id)
select a.customer_id, a.paying_account_id, a.parent_account_id, NVL(ac.admin_id, 'Warning!!') admin_id
  from account a
  left join acc_customers ac
    on ac.account_id = a.paying_account_id
 where a.customer_id = a.paying_account_id
;

以下是我的结果:

SQL> with acc_hierarchy as
  2   (select level lev, ac.*, connect_by_root(ac.paying_account_id) account_id
  3      from account ac
  4    connect by prior ac.parent_account_id = ac.paying_account_id
  5           and prior ac.paying_account_id <> prior ac.parent_account_id),
  6  acc_customers as
  7   (select ah.account_id, min(c.txt01) keep(dense_rank first order by ah.lev) admin_id
  8      from acc_hierarchy ah
  9      left join (select cus.customer_id, cus.txt01
 10                  from customer cus
 11                  join customer_group cg
 12                    on cg.customer_id = cus.customer_id
 13                   and cg."GROUP" = 'E') c
 14        on c.customer_id = ah.customer_id
 15     where c.txt01 is not null
 16     group by ah.account_id)
 17  select a.customer_id, a.paying_account_id, a.parent_account_id, NVL(ac.admin_id, 'Warning!!') admin_id
 18    from account a
 19    left join acc_customers ac
 20      on ac.account_id = a.paying_account_id
 21   where a.customer_id = a.paying_account_id;

CUSTOMER_ID PAYING_ACCOUNT_ID PARENT_ACCOUNT_ID ADMIN_ID
----------- ----------------- ----------------- --------------------
    3271516           3271516            719216 TOM
    1819276           1819276            810546 JIM
     719216            719216            719216 TOM
     810546            810546            810547 JIM
     810547            810547            810547 JIM
     111111            111111            111111 BEN
     123456            123456               231 Warning!!
        231               231               231 Warning!!

8 rows selected.