子查询

一、子查询一般形式
 表T1有一个SALARY,薪水列。我想知道都是谁的薪水比Joe的薪水多。这样的需求,我们共需要两个查询,才能完成,第一个查询是找出Joe的薪水是多少,第二个查询在此基础上,查找比Joe薪水多的人。命令的形式为:


gyj@OCM> select name from t1 where salary > (select salary from t1 where name='Joe');

NAME
----------
Tom


查寻结果,Tom比Joe薪水高。子查寻的形式,就像上面这样,非常的简单。把一个查寻放在括号中,它的结果被另一个查寻使用,这就是子查寻。括号是子查寻必不可少的。子查寻是一个单独的查寻,它可以使用查寻一切的功能,比如ORDER BY、GROUP BY等等。一个主查寻中,可以有多个子查寻。而且,子查寻中,可以再有子查寻,也就是子查寻可以嵌套。嵌套层数ORACLE没有限制,它只限于你的内存大小。子查寻根据所返回行数的不同,可以分为单行子查询和多行子查询,我们先从单行子查询开始。

 

二、单行子查询
1、由于单行子查询在括号内只返回一个值,就像上面那个例子中一样,
select name from t1 where salary > (select salary from t1 where name='Joe');,你可以把()括号中的子查询看作一个数据。和SALARY列作比较的是,就好像是一个普通的数值一样。因此,各种适用于数值的运算符,都可以使用在此处。不但WHERE条件中可以使用子查询,我们也可以把它使用在GROUP BY 中的HAVING条件中。在T1表中,有部门编号(DEPARTMENT_ID)列,和薪水(SALARY)列,我现在想找出哪个部门的平均薪水最低:


 gyj@OCM> select department_id,avg(salary)
  2   from t1
  3   group by department_id having avg(salary)=
  4  ( select min(avg(salary)) from t1 group by department_id );

DEPARTMENT_ID AVG(SALARY)
------------- -----------
            2       11000
 
在查询中,我们通过如下语句:select min(avg(salary)) from t1 group by department_id ,求出了各个部门中,平均薪水最低的薪水数是多少。然后,和主查询中各部门的avg(salary) 比较。最终结果,2号部门的平均薪水最低。

2、单行子查询容易出现的错误:最容易出现的错误,就是单行子查询返回了多行。
我们看前面的已经实验过的例子,查找谁的薪水比Joe的薪水多。


gyj@OCM> select name from t1 where salary > (select salary from t1 where name='Joe');

NAME
----------
Tom


到目前为止,这个命令的执行,是准确无误的。但是,如果T1中的名叫Joe的行,不只一行呢,下面我们再添加一个Joe。


gyj@OCM> insert into t1 values(5,'Joe',8000,sysdate,3);

1 row created.

gyj@OCM> commit;

Commit complete


再次执行看谁的工资比Joe多的查寻:


sgyj@OCM> select name from t1 where salary > (select salary from t1 where name='Joe');
select name from t1 where salary > (select salary from t1 where name='Joe')
                                    *
ERROR at line 1:
ORA-01427: single-row subquery returns more than one row


报出了错误。比较运算符“ > ”,只能对一行数据运算。而现在有了两个Joe,错误就出现了。对于这种情况,有两种解决办法。一是:使用MAX()函数,从两个Joe中,返回工资最多的。以此数值为标准,看谁的工资大于此数值。语句如下:


gyj@OCM>  select name from t1 where salary > (select max(salary) from t1 where name='Joe');

NAME
----------
Tom 


非常简单,只是在子查询中的SALARY外,加了个组函数MAX。当然,这里根据需要,你也可以使用MIN。只需要把子查询返回的两个值,变为一个值,整个查询就没有问题了。
这是一种方法,还有一种方法,就是使用“多行子查询”。


三、多行子查询
返回多行的子查询,就是多行子查询。
在我们上面的例子中,子查询返回多行并没有错,没有规定子查询只能返回一行。错的是>“大于”运算符。它只是一个普通的运算符,一次只能对大于号两端的一对数字进行操作。我们需要在大于运算符后,再使用额外的运算符,让大于、小于等比较运算符可以针对多行数据。这个额外的运算有如下三个ANY 、ALL和IN。
ANY是任意的意思。如果 A  >ANY  (1,2,3,4,5) ,意为A大于(1,2,3,4,5)中,任意一个就行。
ALL是所有,如果A >ALL  (1,2,3,4,5),意为A大于(1,2,3,4,5)中,所有的数。
IN比较特殊,我们在第一章已经讲过了,除了IN之外,还有NOT IN。它不和大于、等于、小于等等这些比较运算符一起使用,它单独使用。A  IN  (1,2,3,4,5),就是判断A是否等(1,2,3,4,5)中的任一个。相当于A  =ANY  (1,2,3,4,5)。而A  NOT IN  (1,2,3,4,5),则是A不等于(1,2,3,4,5)中的所有数,相等于,A  <>ALL  (1,2,3,4,5) 。
它们三个都可以对多行数据进行处理,下面,把那个查看谁比Joe工资多的例子用它们三个重写一下:


gyj@OCM>  select name from t1 where salary > ALL(select salary from t1 where name='Joe');

NAME
----------
Tom 


它的郊果和select name from t1 where salary > (select max(salary) from t1 where name='Joe');是一样的。





**********本博客所有内容均为原创,如有转载请注明作者和出处!!!**********
Name:    guoyJoe

QQ:        252803295

Email:    [email protected]

Blog:      http://blog.csdn.net/guoyJoe

ITPUB:   http://www.itpub.net/space-uid-28460966.html

OCM:     http://education.oracle.com/education/otn/YGuo.HTM
 _____________________________________________________________
加群验证问题:哪些SGA结构是必需的,哪些是可选的?否则拒绝申请!!!

答案在:http://blog.csdn.net/guoyjoe/article/details/8624392

Oracle@Paradise  总群:127149411

Oracle@Paradise No.1群:177089463(已满)

Oracle@Paradise No.2群:121341761

Oracle@Paradise No.3群:140856036



 

你可能感兴趣的:(子查询)