zoukankan      html  css  js  c++  java
  • 层次化查询(start with…connect by prior)

    这里将介绍层次化查询  start with  ...   connect by prior

    语法:

    SELECT [LEVEL], column,expression,...  FROM table WHERE [WHERE where_cause]

    [[START WITH start_condition] [CONNECT BY PRIOR prior_conditon]]

    LEVEL:伪列,代表位于树的第几层。对根节点来说,LEVEL返回1,根节点返回2,依次类推。

    start_condition:定义层次化的起点。层次化查询必须指定START WITH。

    prior_conditon:定义了父行与子行之间的关系。层次化查询必须指定CONNECT BY PRIOR。



    CREATE TABLE more_employees (
      employee_id INTEGER
        CONSTRAINT more_employees_pk PRIMARY KEY,
      manager_id INTEGER
        CONSTRAINT more_empl_fk_fk_more_empl
        REFERENCES more_employees(employee_id),
      first_name VARCHAR2(10) NOT NULL,
      last_name VARCHAR2(10) NOT NULL,
      title VARCHAR2(20),
      salary NUMBER(6, 0)
    );

    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  1, NULL, 'James', 'Smith', 'CEO', 800000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  2, 1, 'Ron', 'Johnson', 'Sales Manager', 600000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  3, 2, 'Fred', 'Hobbs', 'Sales Person', 200000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  4, 1, 'Susan', 'Jones', 'Support Manager', 500000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  5, 2, 'Rob', 'Green', 'Sales Person', 40000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  6, 4, 'Jane', 'Brown', 'Support Person', 45000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  7, 4, 'John', 'Grey', 'Support Manager', 30000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  8, 7, 'Jean', 'Blue', 'Support Person', 29000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  9, 6, 'Henry', 'Heyson', 'Support Person', 30000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  10, 1, 'Kevin', 'Black', 'Ops Manager', 100000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  11, 10, 'Keith', 'Long', 'Ops Person', 50000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  12, 10, 'Frank', 'Howard', 'Ops Person', 45000);
    INSERT INTO more_employees (  employee_id, manager_id, first_name, last_name, title, salary) VALUES (  13, 10, 'Doreen', 'Penn', 'Ops Person', 47000);
    commit ;



    1、使用伪列LEVEL

    select level,employee_id ,manager_id ,first_name ,last_name
    from more_employees
    start with employee_id = 1
    connect by prior employee_id = manager_id
    order by level ;

           LEVEL  EMPLOYEE_ID   MANAGER_ID FIRST_NAME LAST_NAME
    ------------ ------------ ------------ ---------- ----------
               1            1              James      Smith
               2           10            1 Kevin      Black
               2            2            1 Ron        Johnson
               2            4            1 Susan      Jones
               3           13           10 Doreen     Penn
               3            7            4 John       Grey
               3           11           10 Keith      Long
               3            5            2 Rob        Green
               3            3            2 Fred       Hobbs
               3           12           10 Frank      Howard
               3            6            4 Jane       Brown
               4            8            7 Jean       Blue
               4            9            6 Henry      Heyson

    13 rows selected.

    2、格式化层次查询

    select level,
           lpad(' ',10*level - 10) || first_name || ' ' || last_name,
           employee_id ,
           manager_id
    from more_employees
    start with employee_id = 1
    connect by prior employee_id = manager_id ;

    3、从非根节点开始遍历(start with 限制)


    select level,
           lpad(' ',10*level - 10) || first_name || ' ' || last_name,
           employee_id ,
           manager_id
    from more_employees
    start with last_name = 'Jones'
    connect by prior employee_id = manager_id ;

    4、在START WITHE子句中使用子查询

    select level,
           lpad(' ',10*level - 10) || first_name || ' ' || last_name,
           employee_id ,
           manager_id
    from more_employees
    start with employee_id =
      (select employee_id from more_employees where first_name = 'Kevin' and last_name = 'Black')
    connect by prior employee_id = manager_id ;

    5、从下往上遍历

       可以从某个子节点开始,自下而上进行遍历

    select level,
           lpad(' ',10*level - 10) || first_name || ' ' || last_name,
           employee_id ,
           manager_id
    from more_employees
    start with employee_id = 9
    connect by prior  manager_id = employee_id ;

    6、从层次查询中删除节点和分支

       只过滤某些行。用where限制

    select level,
           lpad(' ',10*level - 10) || first_name || ' ' || last_name,
           employee_id ,
           manager_id
    from more_employees
    where last_name <> 'Johnson'
    start with employee_id = 1
    connect by prior employee_id = manager_id ;

        过滤父节点下的所有子节点。用connect by prior ...  and

    select level,
           lpad(' ',10*level - 10) || first_name || ' ' || last_name,
           employee_id ,
           manager_id
    from more_employees
    start with employee_id = 1
    connect by prior employee_id = manager_id and last_name <> 'Johnson' ;



    注意:

        如果 start with 后面是子节点: connect by prior 后面要是 子节点 = 父节点,则是典型的父子结构 ;connect by prior 后面要是 父节点 = 子节点, 将是 子父结构(倒序)。

        如果 start with 后面是父节点:后面要是 子节点 = 父节点,将是正序 ;connect by prior 后面要是 父节点 = 子节点 ,将是 子父结构(倒序),并且数据只有 父节点 和 子节点 2级,其孙子节点及其它的都没有 。
    魔兽就是毒瘤,大家千万不要玩。
  • 相关阅读:
    Linux 性能监测:CPU
    Linux 性能监测:介绍
    数据库设计
    数据库设计
    如何将Virtualbox和VMware虚拟机相互转换
    如何将Virtualbox和VMware虚拟机相互转换
    stat()获得文件信息
    stat()获得文件信息
    网游创业为什么会失败?
    网游创业为什么会失败?
  • 原文地址:https://www.cnblogs.com/tracy/p/1940200.html
Copyright © 2011-2022 走看看