2016-10-02 3 views
3

У меня есть две отдельные таблицы оракула, каждая из которых имеет иерархию. Они связаны ключом ACCOUNT_TYPE. Определение таблицы 1 как таковое.Запрос иерархии Sql с двумя таблицами

CREATE TABLE ACCOUNTS(
    ACCOUNT_CODE VARCHAR2(6), 
    ACCOUNT_PRED VARCHAR2(6), 
    ACCOUNT_TYPE VARCHAR2(6), 
    ACCOUNT_TITLE VARCHAR2(100) 
    ); 

определения таблицы 2, как, например

CREATE TABLE ACCOUNT_TYPES(
    ACCOUNT_TYPE VARCHAR2(6), 
    ACCOUNT_NUMBER_PRED VARCHAR2(6), 
    ACCOUNT_TITLE VARCHAR(100) 
    ); 

Таблица 1 содержит следующие данные

Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0001',null,'11','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0042','0070','13','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0054','0110','13','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0056','0070','13','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0070',null,'13','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0110',null,'13','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0172','0171','13','xxxx'); 
Insert into HR.ACCOUNTS (ACCOUNT_CODE,ACCOUNT_PRED,ACCOUNT_TYPE,ACCOUNT_TITLE) values ('0060','0001','11','XXXX'); 

таблица два содержит следующие данные

REM INSERTING into ACCOUNT_TYPES 
SET DEFINE OFF; 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('10',null,'xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('11','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('12','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('13','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('14','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('15','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('16','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('17','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('18','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('19','10','xxxx'); 
Insert into ACCOUNT_TYPES (ACCOUNT_TYPE,ACCOUNT_NUMBER_PRED,ACCOUNT_TITLE) values ('1A','10','xxxx'); 

можно запустить иератический запрос вроде

SELECT lpad(' ', (level -1) * 3) || ACCOUNT_CODE AS ACCOUNT_CODE, 
      ACCOUNT_TITLE TITLE, 
      ACCOUNT_PRED PRED, 
      ACCOUNT_TYPE ATYPE 
    FROM ACCOUNTS 
    CONNECT BY PRIOR ACCOUNT_CODE = ACCOUNT_PRED 
    START WITH  ACCOUNT_PRED IS NULL 

и другой, как так

SELECT lpad(' ', (level -1) * 3) ||ACCOUNT_TYPE , 
      ACCOUNT_TITLE, 
      ACCOUNT_NUMBER_PRED 
    FROM ACCOUNT_TYPES 
    CONNECT BY PRIOR ACCOUNT_TYPE = ACCOUNT_NUMBER_PRED 
    START WITH ACCOUNT_NUMBER_PRED IS NULL; 

запросов можно было бы по существу возвращать эти значения

0001 
    0060 
0070 
0042 
0056 
0110 
0054 

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

11 
    0001 
    0060 
13 
    0070 
    0042 
    0056 
    0110 
    0054 

Может кто-нибудь помочь мне произвести запрос, который будет включать в себя, по существу типа счета в качестве первого уровня, а затем под ними набор счетов, которые представляли бы под этими счетами.

Любая помощь была бы принята с благодарностью.

+1

Удалены MySQL тег, так как вы используете 'CONNECT WITH' который поддерживает Oracle. –

ответ

2

При условии, что ключи учетных записей и типы учетных записей являются дизъюнктивными, этот запрос обогащает ваш набор данных с помощью верхнего уровня учетной записи по иерархии. (В случае, если ключи учетной записи могут быть одинаковыми, добавьте некоторый префикс в отдельный).

select ACCOUNT_CODE, nvl(ACCOUNT_PRED,ACCOUNT_TYPE) ACCOUNT_PRED, ACCOUNT_TITLE from ACCOUNTS 
union all 
select ACCOUNT_TYPE ACCOUNT_CODE, null ACCOUNT_PRED, ACCOUNT_TITLE from ACCOUNT_TYPES where ACCOUNT_TYPE in (
    select ACCOUNT_TYPE from ACCOUNTS where ACCOUNT_PRED is NULL) 

Обратите внимание, что верхняя часть простых переключатели от верхнего уровня (нуль) до соответствующего типа учетной записи, используя NVL. Вторая часть добавляет недостающий уровень типа учетной записи.

Используя это как источник, просто применяйте свой иерархический запрос.

with acc as (  
select ACCOUNT_CODE, nvl(ACCOUNT_PRED,ACCOUNT_TYPE) ACCOUNT_PRED, ACCOUNT_TITLE from ACCOUNTS 
union all 
select ACCOUNT_TYPE ACCOUNT_CODE, null ACCOUNT_PRED, ACCOUNT_TITLE from ACCOUNT_TYPES where ACCOUNT_TYPE in (
    select ACCOUNT_TYPE from ACCOUNTS where ACCOUNT_PRED is NULL) 
) 
SELECT lpad(' ', (level -1) * 3) || ACCOUNT_CODE AS ACCOUNT_CODE, 
      ACCOUNT_TITLE TITLE, 
      ACCOUNT_PRED PRED 
    FROM ACC 
    CONNECT BY PRIOR ACCOUNT_CODE = ACCOUNT_PRED 
    START WITH  ACCOUNT_PRED IS NULL; 

, которые производят результат, как и ожидалось:

ACCOUNT_CODE TITLE PRED 
--------------- ------ ------ 
11    xxxx   
    0001   xxxx 11  
     0060  XXXX 0001 
13    xxxx   
    0070   xxxx 13  
     0042  xxxx 0070 
     0056  xxxx 0070 
    0110   xxxx 13  
     0054  xxxx 0110 
+0

Спасибо, Мармит, что это абсолютно здорово! Я очень ценю ваш ответ. – Miguel

0

сделать запрос, который будет preduce вам необходимые данные для иерархии:

select ACCOUNT_CODE, nvl(ac.ACCOUNT_PRED, ac.ACCOUNT_TYPE) 
from ACCOUNT_TYPES at 
join ACCOUNTS ac on (at.ACCOUNT_TYPE = ac.ACCOUNT_TYPE) 

это даст вам Acount «таблицы» (набор данных), где Ваш может быть пред Св тип ACount. Теперь вы можете иметь союз между двумя таблицами и сделать иерархию на результат:

select * 
from 
(SELECT ACCOUNT,PRED 
FROM ACCOUNT_TYPES 

union all 

select ACCOUNT, nvl(ac.ACCOUNT_PRED, ac.ACCOUNT_TYPE) as PRED 
from ACCOUNT_TYPES at 
join ACCOUNTS ac on (at.ACCOUNT_TYPE = ac.ACCOUNT_TYPE)) 
CONNECT BY PRIOR ACCOUNT = PRED 
START WITH PRED IS NULL 

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

Смежные вопросы