程序员一年半了,其实到现在我还是不怎么明白那些连接的问题。 特别是当业务复杂的时候,我很担心连接出来的数据有很多冗余,所有很多时候,用子查询,in  和 not in 和外连接似乎更有把握些。 select * from tb_class 
select * from tb_student 
select * from tb_class  c where c.classid in (select distinct(t.stu_classid)  from tb_student t) 要达到这个效果。用连接可以达到吗?
select c.* from tb_class , tb_student   where ??????????????????
---------------------------------------------------------------------------------------------
有没有什么书,可以让我比较清楚学习各种连接。  至少不会犯错误。 
---------------------------------------------------------------------------------------------
假设班级表有一个属性:班级得分。select s.* , c.score   from tb_student s , tb_class   c where  s.stu_classid = c.classid   and s.age>16 我想求:所有在所有大于16岁的学生,所在的班级的 班级得分的总和。 以下语句肯定重复计算了。  有没有什么办法,
在不改变【】外的固定语句情况下,查询到我想要的结果。
select 【 sum(c.score) 】  from tb_student s , tb_class   c where  s.stu_classid = c.classid  and s.age>16  
--- 不对

解决方案 »

  1.   

    select * from tb_class c where c.classid in (select distinct(t.stu_classid) from tb_student t)  select c.* from tb_class c, tb_student s where s.stu_classid = c.classid
    select sum(c.score) from tb_student s , tb_class c where s.stu_classid = c.classid and s.age>16  
    group by c.classid
      

  2.   

    楼上正解,Oracle表连接分内连接与外连接.
    内连接(inner join),相当于取交集,即2个表的共有部分.
    外连接(outer join)分为
      左连接(left join),左表+公共部分.
      右连接(right join),右表+公共部分.
      

  3.   

    不确定的做个测试就知道了,建议参考一下SQL基础语法方面的书即可.
      

  4.   

    是不好在不修改括号外面的情况下弄出来,"所有在所有大于16岁的学生,所在的班级的 班级得分的总和。" 这句话有错别字,不是很清楚。1. 如果是:所有学生都大于 16 岁的班级的得分总和:select sum(SCORE)
    from (
       select sum(c.score) as SCORE
       from tb_student s , tb_class c 
       where s.stu_classid = c.classid 
       group by c.classid
       having min(s.age) > 16  
    ) a
    2. 如果是:至少有一个大于 16 岁的学生的班级的得分总和:select sum(SCORE)
    from (
       select sum(c.score) as SCORE
       from tb_student s , tb_class c 
       where s.stu_classid = c.classid 
       group by c.classid
       having max(s.age) > 16  
    ) a
      

  5.   

    select * from tb_class c where c.classid in (select distinct(t.stu_classid) from tb_student t)  select c.* from tb_class c, tb_student s where s.stu_classid = c.classid-------------------------------------------------------------- 这个好像达不到我想要的结果。其实我一直都没有弄明白? 下面请看如何写。
    表:tb_class  classid:主键
    表:tb_student  stuid:主键   stu_classid:外键(classid) 
    假如:班级表有,20个班级。
    我想查 tb_class 的情况
    select c.*  from tb_class c  where c.classid  in (select distinct(t.stu_classid) from tb_student t)  -----------------------------------------------
    但是如果用:连接。  查出来的结果>20 。  
      

  6.   

    哎,为啥简单的为题大家都抢着回答呢?咱都郁闷了另外,在要说一句,in的在楼主的例子中,可以使用连接两个表来达到目的,但是在别的情况下,这样做是没有效果的。不如使用left join然后再赋予where来的合适。
      

  7.   

    连接的结果是 m * n,因为你的是外键,而且不是为空的,当然在一般情况下都是结果记录数就是 >= m && >= n 的啦。如果取出那些班的总成绩来的话,那主要的表是成绩表,但前提是取整个班级的成绩,而不仅是 > 16 岁的成绩。所以,> 16 这个条件不能直接加在两个表连接后的部分上面,只能加在班级表上,不能影响到成绩表。应该是现在这种,先过滤出来要的班级,再拿班级去连接成绩表。要学习使用子查询,这可是取数据是基本要求,直接拿原来来连接在绝大多数情况下都是达不到复杂的业务要求的。select c.* 
    from tb_class c, (select distinct classid from tb_student s where age>16) s
    where s.stu_classid = c.classid
    ;