Select Oracle 数据库中的树叶

Select tree by leaf in Oracle Database

Oracle 中存在分层查询,使用 CONNECT BY PRIOR。每个人都知道,如何 select 父子 select 子,但我需要 select 父子

这是我的 table:

ID  PID     NAME            TYPE
1   null    EARTH           PLANET
2   1       USA             COUNTRY
3   2       CALIFORNIA      STATE
4   3       Los_Angeles     CITY
5   3       San_Francisco   CITY
6   3       San_Diego       CITY

在我的应用程序中,我的 ID 为 San_Diego,我需要知道 San_Diego 在哪个国家/地区?我需要在查询中获取 USA (TYPE=COUNTRY) 吗?如何select它与oracle层次结构?

没有区别,你只需要在父端使用PRIOR即可。例如获取圣地亚哥市的树:

WITH your_table AS (  
  SELECT 1 id, NULL pid, 'EARTH' name, 'PLANET' type FROM dual
  UNION
  SELECT 2 id, 1 pid, 'USA' name, 'COUNTRY' type FROM dual
  UNION
  SELECT 3 id, 2 pid, 'CALIFORNIA' name, 'STATE' type FROM dual
  UNION 
  SELECT 4 id, 3 pid, 'Los_Angeles' name, 'CITY' type FROM dual
  UNION 
  SELECT 5 id, 3 pid, 'San_Francisco' name, 'CITY' type FROM dual
  UNION
  SELECT 6 id, 3 pid, 'San_Diego' name, 'CITY' type FROM dual
)
SELECT id, name, level
FROM your_table
CONNECT BY id = PRIOR pid
START WITH id = 6

如果你只想得到国家,你可以按级别过滤:

WITH your_table AS (  
  SELECT 1 id, NULL pid, 'EARTH' name, 'PLANET' type FROM dual
  UNION
  SELECT 2 id, 1 pid, 'USA' name, 'COUNTRY' type FROM dual
  UNION
  SELECT 3 id, 2 pid, 'CALIFORNIA' name, 'STATE' type FROM dual
  UNION 
  SELECT 4 id, 3 pid, 'Los_Angeles' name, 'CITY' type FROM dual
  UNION 
  SELECT 5 id, 3 pid, 'San_Francisco' name, 'CITY' type FROM dual
  UNION
  SELECT 6 id, 3 pid, 'San_Diego' name, 'CITY' type FROM dual
)
SELECT id, name, level
FROM your_table
WHERE LEVEL = 3
CONNECT BY id = PRIOR pid
START WITH id = 6

您需要为 connect by 创建正确的条件并从叶子 'San Diego':

开始
select name 
  from (
    select * from test 
      connect by id = prior pid
      start with name='San_Diego')
  where type='COUNTRY'

SQL Fiddle demo

SELECT * FROM places_table
WHERE type = 'COUNTRY'
START WITH id = 6 -- San Diego
CONNECT BY PRIOR pid = id;

层次结构意味着,table 的一行是 "parent",而另一行是 "child"。 PRIOR 用于显示谁是谁。子句 CONNECT BY PRIOR EMPNO = MGR 表示,如果两行具有相同的值,但一行在 EMPNO 列中,而第二行在 MGR 列中,则第二个是 "parent",第一个是 "child"。所以,查询

SELECT EMPNO,ENAME,MGR,LEVEL
FROM TMP_PCH
CONNECT BY PRIOR EMPNO = MGR
START WITH MGR = 'John'

returns John 的所有下属(和 John 本身),并查询

SELECT EMPNO,ENAME,MGR,LEVEL
FROM TMP_PCH
CONNECT BY PRIOR MGR = EMPNO
START WITH MGR = 'John'

returns John 的所有老板(和 John 本身)。