部门表
create table TB_DEPT
(
  ID       NUMBER,
  DEPTNAME VARCHAR2(20)
)
测试数据
1 部门1
2 部门2
3 部门3
员工表
create table tb_user (id number(10),username varchar2(20),age smallint ,depno number(10))
测试数据
1 张三 20 1
2 李四 23 2
3 王五 30 3SQL:
select * from tb_user  where depno in(
select id from tb_dept where username='张三'
)
查询结果
1 张三 20 1问题:
这个sql 语句 是如何执行的,tb_dept 表中没有username 字段 如何能查出结果来 ,哪位大侠给解释一下。 SQLSELECT

解决方案 »

  1.   

    子查询是另外一张表的时候,优化器会自动为两张表做连同名列的等值接,在整合的结果集中查询username呗
      

  2.   

    看sql语句的执行情况,我推荐你看看执行计划。这是很经典的
      

  3.   

    先分析子查询语句
    然后再根据条件检索而且你的SQL语句检索的内容是tb_user表 不是tb_dept表
    tb_dept的检索  只是作为  tb_user表检索的条件而已
      

  4.   

    先执行最里层()内的查询语句 :select id from tb_dept where username='张三' 得到 tb_dept 的id 所有值
    select * from tb_user  where depno in( id的所有值 )
      

  5.   

    因为子查询是会产生一个形如集合的,父查询就根据对应的deptno是否在子查询的集合就可以找到对应的信息,当然你这种写法比较怪的,子查询中用到了父表的字段,这个在sql中称为关联子查询,由于其在子表中没有匹配字段,因此子查询的部门编号应该是所有的部门编号,这样问题就来了,既然是所有的部门编号那就应该显示所有的用户,我认为SQL是进行了优化,它把内部的username='张三'作为外层的约束条件,因此结果就是一条了。select * from tb_user  where depno in(
    select id from tb_dept where username='张三'
    )
      

  6.   

    写成完整的关联子查询
    select * from tb_user where depno exists(select id from tb_dept where tb_user.username=tb.dept and username='张三');
      

  7.   

    应该指定别名,如下。当没有指定别名时, oracle 认为username是表tb_user的。
    select * from tb_user u  where u.depno in(
    select d.id from tb_dept d where u.username='张三'
    )所以,上面的写相当于。
    select * from tb_user u  where u.depno in(
    select d.id from tb_dept d 
    )
    and u.username='张三'http://item.taobao.com/item.htm?spm=686.1000925.1000774.41.OGsWSi&id=20111213320