首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 冲浪宝典 > 网络资源 > Oracle培训笔记20060412
【标  题】:Oracle培训笔记20060412
【关键字】:Oracle,20060412
【来  源】:http://blog.csdn.net/sunjavaduke/archive/2007/03/01/1518215.aspx

Oracle培训笔记20060412

WHERE条件中的子查询
 IN的多列比较
WHERE(A1,A2,....An) IN (SELECT C1,C2,...Cn FROM...)
练习1:SALARY表中有职工在各个月份的工资
QX_INFO表中有在各个月中缺勤的情况的职工信息
如果职工有缺勤,则扣除当月工资的10%,请查询哪些职工需要扣钱
select empno,sal*0.1
from salary
where (empno,ym) in (select empno,ym from qx_info);
in比较多列时,最好放在一列上进行比较
select empno,sal*0.1
from salary
where empno in (select empno from qx_info)
and ym in (select ym from qx_info);
像上面这种查询将列出三行记录

相关子查询:在子查询中引用主查询的列值
例如:查询谁的工资是其所在部门的工资最高的
select * from emp A
where sal=(select max(sal) from emp B
       where B.deptno=A.deptno);

练习二:查询谁的工资高于其所在部门的平均工资
SQL> select *
  2  from emp A
  3  where sal>
  4  (select avg(sal)
  5  from emp B
  6  where A.deptno=B.deptno);

练习:查询各个时间段的产量:rongji表
RTIM       LJRL
---- ----------
0901        800
1002       1500
1059       2700
1200       4100
1400       6000

以前:select B.ljrl-A.ljrl
from rongji A,rongji B
where B.rtim=A.rtim+100;
现在:时间相邻:小的时间是比大的时间小的里面最大的
select B.ljrl-A.ljrl
from rongji A,rongji B
where A.rtime=(select max(rtime) from rongji C
 where c.rtime<B.rtime);

SELECT A.RTIME||'->'||B.RTIME PERIOD,B.LJRL-A.LJRL
    FROM RONGJI A, RONGJI B
   WHERE A.RTIME=(SELECT MAX(RTIME) FROM RONGJI C
                   WHERE C.RTIME<B.RTIME)
倒空储油罐(装满后拉走)
select A.RTIME||'->'||B.RTIME,
 case when A.rid=B.rid then B.ljrl-A.ljrl
 else B.ljrl
 end
from rongji A,rongji B
where A.rtime=(select max(rtime) from rongji C
 where c.rtime<B.rtime);


SELECT-LIST中的子查询:用括号写,返回单行单列的记录
select ename,(select Dname from dept wheredeptno=emp.deptno) from emp;

应用上面的子查询,查询每个部门的编号,名称和人数。
SQL> select deptno,(select dname from dept where deptno=emp.deptno)
  2  ,count(deptno)
  3  from emp
  4  group by deptno;

    DEPTNO (SELECTDNAMEFR COUNT(DEPTNO)
---------- -------------- -------------
        10 ACCOUNTING                 3
        20 RESEARCH                   5
        30 SALES                      6

SQL> select deptno,(select dname from dept where deptno=emp.deptno(+)),count(deptno)
  2  from emp
  3  group by deptno;
ERROR 位于第 1 行:
ORA-01705: 无法在关联列中指定外部连接

SQL> select deptno,dname,(select count(*) from emp      2 where emp.deptno=dept.deptno) RS
  3  from dept;
    DEPTNO DNAME                  RS
---------- -------------- ----------
        10 ACCOUNTING              3
        20 RESEARCH                5
        30 SALES                   6
        40 OPERATIONS              0
练习:查询比其所在部门平均工资高的职工的编号,姓名,工资以及高出多少钱?
SELECT EMPNO,ENAME,SAL,
         SAL-(SELECT AVG(SAL) FROM EMP B
               WHERE A.DEPTNO=B.DEPTNO)
   FROM EMP A
   WHERE SAL >(SELECT AVG(SAL) FROM EMP C
                 WHERE A.DEPTNO=C.DEPTNO);
练习:查询比其所在部门平均工资高的职工的编号,姓名,工资,所在部门平均工资,以及高出多少钱?
SQL> SELECT EMPNO,ENAME,SAL,(select avg(sal) from emp B where A.deptno=B.deptno)
 avg,SAL-(SELECT AVG(SAL) FROM EMP B WHERE A.DEPTNO=B.DEPTNO) differ
  2  FROM EMP A
  3     WHERE SAL >(SELECT AVG(SAL) FROM EMP C
  4                   WHERE A.DEPTNO=C.DEPTNO);
虽然(SELECT AVG(SAL) FROM EMP C
        WHERE A.DEPTNO=C.DEPTNO)
是同样的相关子查询,但是要各自执行一次,一但数据庞大,则效率会降低很大。
FROM子句中的子查询:
要求:1与WHERE条件子查询的要求相同
      2如果子查询中的表达式或者函数被主查询引用,则一定要先起个别名
select * from (select ename,sal from emp);
from后面的部分相当于一个虚拟表,不存在列

select income*1.1
from (select ename,sal+nvl(comm,0) income from emp);

select sal+nvl(comm,0)*1.1
from (select ename,sal+nvl(comm,0) income from emp);
上面两个查询中,第一个可以正确执行而第二个不可以,必须要起别名;

select empno,ename,sal,sal-Asal
 from emp A,(select deptno,avg(sal) Asal
 from emp
 group by deptno) B
where A.deptno=B.deptno
 and A.sal>b.Asal;
练习3:查询各个部门工资最高的职员的
       编号,姓名,工资,
       工资与所在部门平均工资的差
       工资与所在部门最低工资的差
select empno,ename,sal,sal-Asal,sal-Msal
 from emp A,(select
   deptno,avg(sal) Asal,
   min(sal) Msal,
   max(sal) MMsal
   from emp
 group by deptno) B
where A.deptno=B.deptno
 and A.sal=B.MMsal;
     EMPNO ENAME             SAL   SAL-ASAL   SAL-MSAL
---------- ---------- ---------- ---------- ----------
      7839 KING             5000 2083.33333       3700
      7788 SCOTT            3000        825       2200
      7902 FORD             3000        825       2200
      7698 BLAKE            2850 1283.33333       1900 

HAVING中的子查询:
 要求:与WHERE条件中的子查询的要求一致。
       子查询如果引用主查询的列,那么这个列必须是group by中的一个分组项
练习:查询哪个部门人数最多?
SQL> select deptno,count(*)
  2     from emp
  3     group by deptno
  4     having count(*)=(select max(count(*)) from emp group by deptno);

    DEPTNO   COUNT(*)
---------- ----------
        30          6
或者:
SQL> select deptno,count(*)
  2     from emp
  3     group by deptno
  4     having count(*)>=all(select count(*) from emp group by deptno);
练习:查询哪个部门人数最少?
SQL> select A.deptno,count(A.empno)
  2     from emp A,dept B
  3     where A.deptno(+)=B.deptno
  4     group by A.deptno
  5     having count(A.empno)=(select min(count(A.empno))
  6     from emp A,dept B
  7     where A.deptno(+)=B.deptno
  8             group by B.deptno);

    DEPTNO COUNT(A.EMPNO)
---------- --------------
                        0

SQL> select B.deptno,B.dname,count(A.empno)
  2     from emp A,dept B
  3     where A.deptno(+)=B.deptno
  4     group by B.deptno,B.dname
  5     having count(A.empno)=(select min(count(A.empno))
  6     from emp A,dept B
  7     where A.deptno(+)=B.deptno
  8             group by B.deptno);

    DEPTNO DNAME          COUNT(A.EMPNO)
---------- -------------- --------------
        40 OPERATIONS                  0
 
  练习2, 查询哪个部门平均工资最高?

   SELECT DEPTNO,AVG(SAL)
     FROM EMP
    GROUP BY DEPTNO
   HAVING AVG(SAL) >= ALL(SELECT AVG(nvl(SAL,0))
                            FROM EMP
                           GROUP BY DEPTNO)

   SELECT DEPTNO,AVG(SAL)
     FROM EMP
    GROUP BY DEPTNO
   HAVING AVG(SAL) = (SELECT MAX(AVG(SAL)) FROM EMP
                       GROUP BY DEPTNO);
练习3,假设RONGJI表中记录了
        某炼油厂的某个油罐
    在各个时间点(rtime)所测量到的
    容量(LJRL)
 
 请查询哪个时间段(相邻两个时间点之间)
  的产量最大?

SELECT *
  FROM (SELECT A.RTIME||'->'||B.RTIME PERIOD,
          CASE WHEN A.RID=B.RID THEN B.LJRL-A.LJRL
               ELSE B.LJRL
          END CL
   FROM RONGJI A, RONGJI B
   WHERE A.RTIME=(SELECT MAX(RTIME) FROM RONGJI C
        WHERE C.RTIME<B.RTIME))
WHERE CL=(SELECT MAX(CL)
            FROM (SELECT A.RTIME||'->'||B.RTIME PERIOD,
          CASE WHEN A.RID=B.RID THEN B.LJRL-A.LJRL
               ELSE B.LJRL
          END CL
      FROM RONGJI A, RONGJI B
        WHERE A.RTIME=(SELECT MAX(RTIME) FROM RONGJI C
                        WHERE C.RTIME<B.RTIME)));

********************************************************
 WITH语句:用来给from子句中出现的子查询起别名
 WITH A AS (SELECT ....)
 SELECT * FROM A;
  相当于
 SELECT * FROM (SELECT ...)

练习3,查询比其所在部门平均工资高的职工的
       编号,姓名,工资,所在部门平均工资
       以及高出所在部门的平均工资多少钱?           

  WITH B AS(SELECT DEPTNO,AVG(SAL) ASAL
                   FROM EMP
                 GROUP BY DEPTNO)
   SELECT EMPNO,ENAME,SAL,SAL-ASAL
     FROM EMP A,B
    WHERE A.DEPTNO=B.DEPTNO
      AND A.SAL>B.ASAL 

改写练习:假设RONGJI表中记录了
    某炼油厂的某个油罐
    在各个时间点(rtime)所测量到的
    容量(LJRL)
    请查询哪个时间段(相邻两个时间点之间)
    的产量最大?
with c as (SELECT A.RTIME||'->'||B.RTIME PERIOD,
          CASE WHEN A.RID=B.RID THEN B.LJRL-A.LJRL
               ELSE B.LJRL
          END CL
   FROM RONGJI A, RONGJI B
   WHERE A.RTIME=(SELECT MAX(RTIME) FROM RONGJI C
        WHERE C.RTIME<B.RTIME))
select * from c
where cl=(select max(cl) from c); 

(select (B.UL-A.UL)/(B.UL-A.UL+B.DL-A.DL)
from bizstat A,bizstat B
where A.GTIME=(select max(gtime) from bizstat C
where C.gtime<B.gtime))
   ************************子查询到此结束了***********************
集合操作:
UNION:并集
UNION ALL:集(不去掉重复的列)
INTERSECT:
MINUS
要求做集合操作的两个查询
必须返回相同数目的列
并且列的数据类型必须完全相同
UNION ALL要比UNION查询速度快
UNION要去掉重复的列
UNION ALL不去掉重复的列
练习1,查询各个部门的名称人数
       以及各种职务的名称和人数

  SELECT DNAME,(SELECT COUNT(*) FROM EMP WHERE DEPTNO=DEPT.DEPTNO)
    FROM DEPT
  UNION  ALL
  SELECT JOB,COUNT(*)
    FROM EMP
   GROUP BY JOB;

练习2,查询各个部门的编号,人数
       以及各种职务的名称,人数

  SELECT TO_CHAR(DEPTNO),COUNT(*)
    FROM EMP
   GROUP BY DEPTNO
  UNION ALL
  SELECT JOB ,COUNT(*)
    FROM EMP
   GROUP BY JOB
练习3,查询各个部门的编号,人数,总工资
        以及各种职务的名称,人数,总工资
        以及全体的人数和总工资      

  SELECT TO_CHAR(DEPTNO),COUNT(*),SUM(SAL)
    FROM EMP
   GROUP BY DEPTNO
  UNION ALL
  SELECT JOB ,COUNT(*),SUM(SAL)
    FROM EMP
   GROUP BY JOB
  UNION ALL
  SELECT '总计:',COUNT(*),SUM(SAL)
    FROM EMP;
   ************************DML数据操作语言**************************

    INSERT

    UPDATE

    DELETE

INSERT

    INSERT INTO 表名 VALUES(值的列表)
    INSERT INTO 表名 (列名列表) VALUES(值的列表)
INSERT INTO EMP
   VALUES(1122,'JA',NULL,NULL,NULL,NULL,NULL,NULL)

INSERT INTO EMP (EMPNO,ENAME) VALUES(1122,'JA')

   INSERT INTO 表名 [(列名列表)] (子查询)
 
   练习1,创建一个表EMP_BK,
         列定义和表中数据与EMP表完全相同  

Oracle培训笔记20060413:【上一篇】
Oracle培训笔记20060410:【下一篇】
【相关文章】
  • Oracle培训笔记20060413
  • Oracle培训笔记20060415
  • Oracle培训笔记20060414
  • Oracle培训笔记20060416
  • Oracle MD5加密的存储过程的实现
  • Oracle与SQL Server的数据同步方法。
  • Oracle中的归档日志(Archive Log)
  • ubundtu Linux 下安装 ORACLE 10G
  • 使用Oracle的PL/SQL发送Email
  • Error:ORA-01033:ORACLE initialization or shutdown in progress错误解决
  • 【随机文章】
  • 节约Windows系统资源六法
  • Linux2.6 内核的 Initrd 机制解析(zt)
  • LMDS--中国移动宽带接入的利器
  • 经济普查全国数据库优化方案
  • 巨头百安居
  • 利用Google作黑客攻击的原理和防范
  • 还有两天河南BOSS1.5要割接了,快解放了
  • RSA算法实现
  • Jflash-s3c2410(linux版本)源码分析
  • Fireworks MX 2004 切片与热点(2)
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.