查询分层表

时间:2014-10-13 19:37:18

标签: sql oracle select

假设我们有这个表SchoolClass

id_class    class       class_Name  id_class_req
--------    --------    ---------   --------
1          SQL9999          SQL     
2          PHP1111          PHP         1
3          JAV2222          Java        2

因此,在尝试此类之前,类可以具有其他类作为要求。我希望能够对每个有要求的课程进行排序,并给出这样的课程:

class       id_class_req
-------     -------------       
PHP1111     SQL9999
JAV222      PHP1111

这是我的查询。我只能通过此查询提供id_class_req。有没有办法在没有子查询或嵌套查询的情况下执行此操作。

SELECT SchoolClass.class, SchoolClass,id_class_req
FROM SchoolClass
WHERE SchoolClass.id_cours_prerequis Is Not Null;

非常感谢你。

4 个答案:

答案 0 :(得分:2)

Oracle有一个很好的功能叫做 hierarchical query ,可以帮助那种表格(即:adjacency list)。有了这个,你可以这样写:

SELECT CONNECT_BY_ROOT "class" as "Root class", "class" AS "Dep class"
FROM T
WHERE LEVEL = 2
CONNECT BY PRIOR "id_class_req" = "id_class";

请参阅http://sqlfiddle.com/#!4/bbbc0/1

在这样的查询中,Oracle将构建一个图形,例如每个节点, node.parent.id_class_req = node.id_class CONNECT BY PRIOR "id_class_req" = "id_class")。之后,我们只保留深度为2的子图(WHERE LEVEL = 2)。事实上,这正是你要找的。


作为一张价值1000字的图片,给出上述查询和样本数据:

id_class    class       class_Name  id_class_req
--------    --------    ---------   --------
1          SQL9999          SQL     
2          PHP1111          PHP         1
3          JAV2222          Java        2
10         LIN101           Linux     
11         C101             C           10
12         SYSADMIN         SysAdmin    10
14         ELEC101          Electronics

Oracle将构建该图:

dot graph

并且只保留长度为2的路径(即:只包含一个子节点及其直接父节点的节点对):

ROOT CLASS  DEP CLASS
PHP1111     SQL9999
JAV2222     PHP1111
C101        LIN101
SYSADMIN    LIN101

答案 1 :(得分:0)

尝试SELF JOIN

SELECT sc1.class, sc2.class 
FROM SchoolClass sc1
INNER JOIN SchoolClass sc2 ON sc1.id_class_req=sc2.id_class

答案 2 :(得分:0)

使用自我加入

执行此操作
SELECT s.class, rec.class
FROM SchoolClass s
INNER JOIN SchoolClass req on s.id_class=req.id_class_req
WHERE SchoolClass.id_cours_prerequis Is Not Null;

答案 3 :(得分:0)

您可以针对同一个表进行内部联接

SELECT m.SchoolClass.class, m.SchoolClass,m.id_class_req, r.class as "Required Class"
FROM SchoolClass m, SchoolClass r
WHERE m.id_class_req = r.id_class    
m.SchoolClass.id_cours_prerequis Is Not Null;