Иерархическая таблица в Oracle - PullRequest
0 голосов
/ 30 апреля 2018

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

Таблица ввода:

|       Agency_CODE         |  Code_length       | Agency_Name    
|              1            |       1            |     Boogy
|              11           |       2            |     Elhady
|              12           |       2            |     EzzBatriq
|              13           |       2            |     Haythomy
|              111          |       3            |     Migz
|              121          |       3            |     Mido
|              131          |       3            |     Thabet

Иерархия должна выглядеть следующим образом: агентство, которое имеет только одну цифру, является корнем иерархии 'Level 1', а level 2 позиции, которая имеет две цифры, и level 3, которая имеет 3 цифры. Здесь у нас есть 3 уровня

Итак, нам нужен запрос, чтобы получить output :

|Parent_ID |Parent_Name|Child_1_Id|Child_1_name|Child_2_Id|Child_2_name|      
|     1    |   Boogy   |    11    |  Elhady    |  111     |  Migz      |
|     1    |   Boogy   |    12    |  EzzBatriq |  121     |  Mido      | 
|     1    |   Boogy   |    13    |  Haythomy  |  131     |  Thabet    |

Заранее спасибо

1 Ответ

0 голосов
/ 30 апреля 2018

SQL Fiddle

Настройка схемы Oracle 11g R2 :

CREATE TABLE Agencies (
  Agency_CODE NUMBER(8,0) CONSTRAINT Agencies__AC__PK PRIMARY KEY,
  Code_length NUMBER(4,0) GENERATED ALWAYS AS ( LENGTH( Agency_Code ) ) VIRTUAL,
  Agency_Name VARCHAR2(50),
  parent_code NUMBER(7,0) GENERATED ALWAYS AS ( SUBSTR( Agency_Code, 1, LENGTH( Agency_Code ) - 1 ) ) VIRTUAL
                          CONSTRAINT Agencies__PC__FK REFERENCES Agencies( Agency_Code )
);

INSERT INTO Agencies ( Agency_CODE, Agency_Name )
SELECT   1, 'Boogy' FROM DUAL UNION ALL
SELECT  11, 'Elhady' FROM DUAL UNION ALL
SELECT  12, 'EzzBatriq' FROM DUAL UNION ALL
SELECT  13, 'Haythomy' FROM DUAL UNION ALL
SELECT 111, 'Migz' FROM DUAL UNION ALL
SELECT 121, 'Mido' FROM DUAL UNION ALL
SELECT 131, 'Thabet' FROM DUAL;

Запрос 1 :

SELECT CONNECT_BY_ROOT( Agency_Code ) AS parent_id,
       CONNECT_BY_ROOT( Agency_name ) AS parent,
       PRIOR( Agency_Code ) AS child_id,
       PRIOR( Agency_name ) AS child,
       Agency_Code AS child2_id,
       Agency_Name AS child2
FROM   Agencies
WHERE  LEVEL = 3
START WITH Code_length = 1
CONNECT BY PRIOR Agency_code = parent_code

Результаты

| PARENT_ID | PARENT | CHILD_ID |     CHILD | CHILD2_ID | CHILD2 |
|-----------|--------|----------|-----------|-----------|--------|
|         1 |  Boogy |       11 |    Elhady |       111 |   Migz |
|         1 |  Boogy |       12 | EzzBatriq |       121 |   Mido |
|         1 |  Boogy |       13 |  Haythomy |       131 | Thabet |

Обновление : если вы знаете максимальную глубину вложенной иерархии, вы можете использовать PIVOT:

SQL Fiddle

Настройка схемы Oracle 11g R2 :

INSERT INTO Agencies ( Agency_CODE, Agency_Name )
SELECT 1311, 'Thabet.1' FROM DUAL;

Запрос 2 :

SELECT *
FROM   (
  SELECT CONNECT_BY_ROOT( Agency_Code ) AS leaf_id,
         Agency_Code,
         code_length,
         Agency_Name
  FROM   Agencies a
  START WITH NOT EXISTS (
    SELECT 1
    FROM   Agencies x
    WHERE  x.parent_code = a.agency_code
  )
  CONNECT BY PRIOR parent_code = Agency_code
) a
PIVOT(
  MAX( agency_code ) AS id,
  MAX( agency_name ) AS name
  FOR code_length IN (
    1 AS parent,
    2 AS child,
    3 AS child1,
    4 AS child2
  )
)

Результаты :

| LEAF_ID | PARENT_ID | PARENT_NAME | CHILD_ID | CHILD_NAME | CHILD1_ID | CHILD1_NAME | CHILD2_ID | CHILD2_NAME |
|---------|-----------|-------------|----------|------------|-----------|-------------|-----------|-------------|
|     121 |         1 |       Boogy |       12 |  EzzBatriq |       121 |        Mido |    (null) |      (null) |
|    1311 |         1 |       Boogy |       13 |   Haythomy |       131 |      Thabet |      1311 |    Thabet.1 |
|     111 |         1 |       Boogy |       11 |     Elhady |       111 |        Migz |    (null) |      (null) |
...