2010-10-12 72 views
1

我有这个疑问:为什么表在SQL查询的FROM子句中的不同别名下存在两次?

SELECT to_number(gr.code) group_index,    
     gr.NAME group_name, f.*,       
     gr.description gr_desc       
     FROM obj$groups gr, obj$group_objects gro,   
     obj$group_objects gro2, tdf$flex_fields f,  
     inv$requests w, inv$Direction_Criterions c  
    WHERE gr.NO = gro.object_no       
     AND gro.group_no = obj$group_service.path_to_no(
     'Some Condition String', 
     tdf$flex_field_service.get_local_list_group_no) 
     AND gro2.group_no = gr.NO       
     AND f.NO = gro2.object_no       
     AND w.no = 11593597        
     AND c.direction_no = w.direction_no    
     AND f.no = c.criterion_no       
    ORDER BY to_number(gr.code), f.name 

为什么有两个相同的表(group_objects)在座?我试图对此进行反向工程,但是本身不能,也许任何人都已经知道这个技巧?

这发生在Oracle数据库中。

回答

3

这是一个名为self-join的操作。当你想要从同一张表中加入记录时。

它通常发生在您有与相同表中的记录相关的记录时。例如:

create table tree 
(
    id number primary key, 
    parent_id number, 
    value varchar2(100) 
); 

所以,如果你想要检索的节点和他们的父母,你会怎么做:

select c.id, c.value, p.value as parent_value 
    from tree c inner join tree p on (c.parent_id = p.id) 

类似的事情是发生在您发布的查询。

+0

自加入在哪里?你的意思是交叉加入? – 2010-10-12 12:42:00

+0

@Preet:不,但是我刚刚改正了一个错字。 TREE表格是自加入的。 – 2010-10-12 12:48:49

+0

@Preet:不,是自联接:加入自己。 :-) – 2010-10-12 12:53:22

1

group_objects正在连接到子句gro2.group_no = gr.NO中的组,并且连接到子句f.NO = gro2.object_no中的flex_fields。我怀疑这涵盖了obe集合对象与另一个集合不完全相同的情况,这限制了两个联接中的行,其中一个联接删除了一个group_object,这些联接将无法加入另一个表中。

1

很难从这段代码中找出原始程序员的意图,尤其是没有描述各种表格的含义。

但是,在我看来好像这个查询的最终结果应该报告来自group_objects表的两个不同记录的信息 - 其中一个组中的no与“Some Condition String”匹配,另一个组中的组号不匹配来自组表的列值。如果我不得不猜测,它将检索一个操作,其中一个项目在两个组之间转移,或者代替替代第二个组中的对象或类似的操作。

1

为了说明,与标准EMP表相当于将是:

select e.ename, m.ename manager_name 
from emp e, emp m 
where m.empno = e.mgr; 

或者在更现代的语法:

select e.ename, m.ename manager_name 
from emp e 
join emp m on m.empno = e.mgr; 

即表明员工与管理者的名称和姓名的经理。

问题是,同一个表在查询中使用了两次不同的“角色”。它不一定是一个自连接,有可能是另一个表(或更多)之间是这样的:

select e.ename, pm.ename projmanager_name 
from emp e 
join project_assignments pa on p.empno = pa.empno 
join projects p on p.proj_id = pa.proj_id 
join emp pm on pm.empno = p.projmanager_empno; 

即表明分配给项目员工的姓名,并显示该项目的项目经理的名字。

相关问题