Oracle中的分层表

Moh*_*san 0 sql oracle hierarchical-data

我有创建分层表的问题,我搜索了很多,但这个问题可能与流行的问题不同.我有需要重建的表

输入表:

|       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
Run Code Online (Sandbox Code Playgroud)

层次结构应为:只有一位数的代理商是层次结构的根'Level 1',以及level 2具有两位数且level 3具有3位数的项目.这里我们有3个级别

所以我们需要一个查询来获得这个输出:

|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    |
Run Code Online (Sandbox Code Playgroud)

提前致谢

MT0*_*MT0 5

SQL小提琴

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;
Run Code Online (Sandbox Code Playgroud)

查询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
Run Code Online (Sandbox Code Playgroud)

结果:

| 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 |
Run Code Online (Sandbox Code Playgroud)

更新:如果您知道嵌套层次结构的最大深度,则可以使用PIVOT:

SQL小提琴

Oracle 11g R2架构设置:

INSERT INTO Agencies ( Agency_CODE, Agency_Name )
SELECT 1311, 'Thabet.1' FROM DUAL;
Run Code Online (Sandbox Code Playgroud)

查询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
  )
)
Run Code Online (Sandbox Code Playgroud)

结果:

| 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) |
Run Code Online (Sandbox Code Playgroud)