Oracle学习笔记-SELECT详解,数据库基本操作

此笔记为韩顺平老师9i的视频随堂笔记,虽然是9i,但重点在表查询上,基本的操作和目前12c很少有差别,操作表为scott用户自带emp/dept表。

12c conn / as sysdba 默认链接到cdb也就是CDB$ROOT
在CDB内不允许创建普通用户,具体报错如下
ORA-65096: invalid common user or role name
只可以创建 c##开头的用户,并且用户会在所有pdb递归创建

12c 已经将默认的scott用户删除,但其自带一个sql,路径如下:
$ORACLE_HOME/rdbms/admin/utlsampl.sql

需要alter session set container=[orclpdb]切换到容器
执行
create user scott identified by tiger; 创建用户
grant connect,resource to scott; 可连接,可建表
再执行@$ORACLE_HOME/rdbms/admin/utlsampl.sql

tips: 脚本内CONNECT SCOTT/tiger这一句需要更改
因为oraclpdb不再是实例,而是实例下container的一个pluggable database
所 改为: connect scott/tiger@localhost/orclpdb再执行


#查看监听的服务
lsnrctl service
#查看监听
lsnrctl status

#运行sql脚本
sql>@script.sql

#提示用户输入变量

select * from dba_users where username='&username';

#登陆
sqlplus username/password@host/instance as role

例子
sqlplus scott/tiger@localhost/orclpdb

sqlplus system/manager@localhost/orclpdb as sysdba


   is: {[/][@] | / }
              [AS {SYSDBA | SYSOPER | SYSASM | SYSBACKUP | SYSDG | SYSKM | SYSRAC}] [EDITION=value]
              


#启动数据库
startup
 where db_options has the following syntax:
    [FORCE] [RESTRICT] [PFILE=filename] [QUIET] [ MOUNT [dbname] |
    [ OPEN [open_db_options] [dbname] ] |
    NOMOUNT ]
    
#显示命令执行时间
set timing on;

#设置行宽度
set linesize 100
#设置页大小
set pagesize 50
#设置列明为con_id的宽度为10个字符串
col con_id format 09.99 #格式为数字,0表示如果没有此位,以0代替,9表示可以有,也可以没有此位,如果有,就显示,没有则不显示
col name format a10
col open_mode format a10
col restricted format a10

#查看当前的容器(12c)
show con_name;


#查看可插拔数据库(PDB)
select CON_ID, NAME, OPEN_MODE, RESTRICTED FROM V$PDBS;
#输出结果
CON_ID NAME       OPEN_MODE  RESTRICTED
------ ---------- ---------- ----------
 03.00 ORCLPDB    READ WRITE NO

#切换会话到容器(pdb)中
alter session set container=ORCLPDB ; 

#查看CDB
select name, cdb from v$database ;

NAME      CDB
--------- ---
ORCL      YES

#关闭一个可插拔数据库
ALTER PLUGGABLE DATABASE ORCLPDB CLOSE [IMMEDIATE];

#打开一个可插拔数据库
ALTER PLUGGABLE DATABASE ORCLPDB OPEN [READ/WRITE/READ ONLY/UPGRADE]; 





#查看当前用户
show user;


#创建用户
create user [username] identified by [password]
#删除用户
drop user [username] [cascade]

#授权
grant [role/权限] to [username]

#例子,为用户授权可以连接数据库
grant connect to scott

#更新用户密码
alter user [username] identified by [password];


#查看用户所拥有的角色
SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE='SCOTT';




#给另一个用户赋权可以访问当前用户的表
grant select,instrt,update,delete on [table] to [username] [with grant option]
                                                            这里为被赋权用户可以继续赋权给其他用户
#例子
grant all on emp to xiaoming;

#回收权限
rovake select,instrt,update,delete on [table] from [username]



#另一个用户访问被其他用户赋权的表
select * from scott.emp;

#创建配置文件
create profile [ProfileName] limit [Args];
#三次输入错误锁定,锁定两天
create profile testprofile1 limit failed_login_attempts 3 password_lock_time 2;
#要求用户10天之内修改密码, 宽限期为2天,10天以后可以重用老密码。
create profile changepassword limit password_life_time 10 password_grace_time 2 password_reuse_time 10;
#查看配置文件
select * from dba_profiles where profile='CHANGEPASSWORD';
#查看用户配置文件
select username,profile from dba_users where username='XIAOMING2';

#删除配置文件 cascade 把相关的东西都删除掉
drop profile [ProfileName] [cascade]

#为用户应用配置文件
alter user xiaoming profile testprofile1 ; 

#用户解锁、锁定
alter user [xiaoming] account [unlock lock]
 

#查看配置文件
select * from dba_profiles;


#建表
create table student(xh number(4), xm varchar2(20), sex char(2), birthday date, sal number(7,2));
#number(7,2) 范围 -99999.99 ~ 99999.99
#添加列
alter table student add (classId number(20));
#修改字段长度
alter table student modify (xm varchar2(40));
#修改字段类型/名(不能有数据)
alter table student modify (xm char(30));
alter table student rename column xm to xm1; 
#删除列
alter table student drop column xm ; 
#修改表名
rename student to stu ; 
#删除表
drop table student;




#增删改查###########################
#操作的相关表,先看一下表结构
SQL> select * from student ; 

        XH XM                                       SEX       BIRTHDAY          SAL    CLASSID
---------- ---------------------------------------- --------- ---------- ---------- ----------
         2 小明                                     男        1990-01-01
         1 小红                                     女        1990-01-01
         

SQL> desc emp;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 EMPNO                                                 NOT NULL NUMBER(4)
 ENAME                                                          VARCHAR2(10)
 JOB                                                            VARCHAR2(9)
 MGR                                                            NUMBER(4)
 HIREDATE                                                       DATE
 SAL                                                            NUMBER(7,2)
 COMM                                                           NUMBER(7,2)
 DEPTNO                                                         NUMBER(2)
 
SQL> select * from emp ;

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980-12-17        800                    20
      7499 ALLEN      SALESMAN        7698 1981-02-20       1600        300         30
      7521 WARD       SALESMAN        7698 1981-02-22       1250        500         30
      7566 JONES      MANAGER         7839 1981-04-02       2975                    20
      7654 MARTIN     SALESMAN        7698 1981-09-28       1250       1400         30
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20
      7839 KING       PRESIDENT            1981-11-17       5000                    10
      7844 TURNER     SALESMAN        7698 1981-09-08       1500          0         30
      7876 ADAMS      CLERK           7788 1987-05-23       1100                    20
      7900 JAMES      CLERK           7698 1981-12-03        950                    30
      7902 FORD       ANALYST         7566 1981-12-03       3000                    20
      7934 MILLER     CLERK           7782 1982-01-23       1300                    10

14 rows selected.

SQL> desc dept ;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                NOT NULL NUMBER(2)
 DNAME                                                          VARCHAR2(14)
 LOC                                                            VARCHAR2(13)
 
SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

        

SQL> desc salgrade ;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 GRADE                                                          NUMBER
 LOSAL                                                          NUMBER
 HISAL                                                          NUMBER
 
SQL> select * from salgrade;

     GRADE      LOSAL      HISAL
---------- ---------- ----------
         1        700       1200
         2       1201       1400
         3       1401       2000
         4       2001       3000
         5       3001       9999

Elapsed: 00:00:00.01


 

#增
insert into student values(1,'xm','b','08-SEP-81',1500);
insert into student(xm,xh,sex) values('小明',2,'男') ;
#删
delete student where xh=1;
#改
UPDATE SCOTT.EMP SET JOB='ENG',MGR=1000  WHERE ENAME='TEA';
update student set sal=sal/2 where sex='男';
update student set classid=1 where classid is null ;
#先查后改
#把工资低于平均工资,并且入职日期在1982年前的老员工的工资提升百分之10
update emp set sal=sal*1.1 where empno in (select empno from emp where sal<(select avg(sal) from emp) and HIREDATE>to_timestamp('1982-1-1','yyyy-mm-dd'));

############查
select * from student ;
select * from student where sal is null;
select * from student where sal is not null ;
select distinct job from emp ; # 不显示重复的数据

#计算每个人的年工资,nvl函数类似python getattr(),如果取到的值为null,则设置为0
select ename,sal*13+nvl(comm,0)*13 年工资 from emp order by 年工资 desc; 

#查询大于3000的工资的人,按工资从多到少排序
select * from emp where sal >3000 order by sal desc ;

#查询1982-1-1之后入职的员工
select ename,hiredate from emp where hiredate>to_timestamp('1982-1-1','yyyy-mm-dd');

#查询1982-1-1之后入职的员工,工资在2000-3500之间的员工
select ename,hiredate from emp where hiredate>to_timestamp('1982-1-1','yyyy-mm-dd') and sal>=2000 and sal<=3500;



#TIPS
#like操作符
%表示0到多个字符
_表示单个字符


#显示名字内有TT的员工
select ename,sal from emp where ename like '%TT';
#显示名字为S开头的员工
select ename,sal from emp where ename like 'S%';
#显示名字内第三个字母为O的员工
select ename,sal from emp where ename like '__O%';

#where in()查询  查询in()括号内的数据,类似for i in
#查询员工号为7369,7499,7521的员工
select * from emp where EMPNO in (7369,7499,7521);


#查询MGR为NULL的员工
select * from emp where mgr is null;

#查询工资大于500或者工作为manager并且ename首字母为J的员工,并按照工资排序
select * from emp where (sal>500 or JOB='MANAGER') and ename like 'J%' order by sal asc;

#按照部门升序,每一个部门按员工降序
select deptno,ename,sal*12+nvl(comm,0) "年薪" from emp order by deptno asc,sal desc;

#按照年薪,使用别名排序
select deptno,ename,sal*12+nvl(comm,0) "年薪" from emp order by "年薪" desc;

#查询最高工资,最低工资的数值
select max(sal) "max", min(sal) "min" from emp;

#查询工资最高的人是谁,工资是多少
select ename,sal from emp where sal=(select max(sal) from emp);

#查询工资高于平均工资的员工的信息
select * from emp where sal>(select avg(sal) from emp ) ; 

#把工资低于平均工资,并且入职日期在1982年前的老员工的工资提升百分之10
update emp set sal=sal*1.1 where empno in (select empno from emp where sal<(select avg(sal) from emp) and HIREDATE>to_timestamp('1982-1-1','yyyy-mm-dd'));

#group by 用于分组统计
#having 用户限制分组显示结果

#按照部门求平均工资,最低工资
select avg(sal) "平均工资" ,min(sal) "最低工资" ,deptno "部门编号" from emp group by deptno;

  平均工资   最低工资   部门编号
---------- ---------- ----------
1566.66667        950         30
      2175        800         20
2916.66667       1300         10


#求每个部门的每种职位的平均工资,按照部门编号和平均工资升序
select deptno,job,avg(sal) "pjgz" ,min(sal) from emp group by deptno,job order by deptno,"pjgz";

#显示平均工资低于2000的部门号和他的平均工资
col 平均工资 format 999999.99
select deptno, avg(sal) "平均工资" from emp group by deptno having avg(sal) > 2000 order by deptno;
    DEPTNO   平均工资
---------- ----------
        20    2175.00
        10    2916.67


#TIPS
#分组函数只能出现在选择列表、having、order by子语句
#如果在一个select语句中同时包含group by, having, order by,那么顺序必须是 group by --> having  --> order by

#多表查询
#查询员工的姓名,工资,部门,城市(部门,城市为其他表)

SELECT EMP.ENAME, EMP.SAL, DEPT.DNAME, DEPT.LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;
SELECT A1.ENAME, A1.SAL, A2.DNAME, A2.LOC FROM EMP A1, DEPT A2 WHERE A1.DEPTNO=A2.DEPTNO;


ENAME             SAL DNAME          LOC
---------- ---------- -------------- -------------
CLARK            2450 ACCOUNTING     NEW YORK
KING             5000 ACCOUNTING     NEW YORK
MILLER           1300 ACCOUNTING     NEW YORK
JONES            2975 RESEARCH       DALLAS
FORD             3000 RESEARCH       DALLAS
ADAMS            1100 RESEARCH       DALLAS
SMITH             800 RESEARCH       DALLAS
SCOTT            3000 RESEARCH       DALLAS
WARD             1250 SALES          CHICAGO
TURNER           1500 SALES          CHICAGO
ALLEN            1600 SALES          CHICAGO
JAMES             950 SALES          CHICAGO
BLAKE            2850 SALES          CHICAGO
MARTIN           1250 SALES          CHICAGO


#查询部门平均工资,部门名称
col "平均工资" format 99999999.99
select avg(a1.sal) as "平均工资", a2.dname from emp a1,dept a2 where a1.deptno=a2.deptno group by a2.dname order by "平均工资";

  平均工资 DNAME
---------- --------------
   1566.67 SALES
   2175.00 RESEARCH
   2916.67 ACCOUNTING

#多表查询详解(笛卡尔集)
SQL> select * from emp where ename='MARTIN';

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------ ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30

SQL> 
SQL> select * from dept ;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL> select * from emp,dept where ename='MARTIN';

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO     DEPTNO DNAME          LOC
---------- ---------- --------- ---------- ------------------ ---------- ---------- ---------- ---------- -------------- -------------
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30         10 ACCOUNTING     NEW YORK
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30         20 RESEARCH       DALLAS
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30         30 SALES          CHICAGO
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30         40 OPERATIONS     BOSTON

#笛卡尔集筛选(排除),笛卡尔集是相当危险的,会导致select结果成幂增长,如果有n个表,至少需要n-1个条件才能排除笛卡尔集
SQL> select * from emp,dept where emp.deptno=dept.deptno;

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO     DEPTNO DNAME          LOC
---------- ---------- --------- ---------- ------------------ ---------- ---------- ---------- ---------- -------------- -------------
      7782 CLARK      MANAGER         7839 09-JUN-81                2450                    10         10 ACCOUNTING     NEW YORK
      7839 KING       PRESIDENT            17-NOV-81                5000                    10         10 ACCOUNTING     NEW YORK
      7934 MILLER     CLERK           7782 23-JAN-82                1300                    10         10 ACCOUNTING     NEW YORK
      7566 JONES      MANAGER         7839 02-APR-81                2975                    20         20 RESEARCH       DALLAS
      7902 FORD       ANALYST         7566 03-DEC-81                3000                    20         20 RESEARCH       DALLAS
      7876 ADAMS      CLERK           7788 23-MAY-87                1100                    20         20 RESEARCH       DALLAS
      7369 SMITH      CLERK           7902 17-DEC-80                 800                    20         20 RESEARCH       DALLAS
      7788 SCOTT      ANALYST         7566 19-APR-87                3000                    20         20 RESEARCH       DALLAS
      7521 WARD       SALESMAN        7698 22-FEB-81                1250        500         30         30 SALES          CHICAGO
      7844 TURNER     SALESMAN        7698 08-SEP-81                1500          0         30         30 SALES          CHICAGO
      7499 ALLEN      SALESMAN        7698 20-FEB-81                1600        300         30         30 SALES          CHICAGO
      7900 JAMES      CLERK           7698 03-DEC-81                 950                    30         30 SALES          CHICAGO
      7698 BLAKE      MANAGER         7839 01-MAY-81                2850                    30         30 SALES          CHICAGO
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30         30 SALES          CHICAGO


#查询比30号部门最高工资高的员工
select * from emp where sal>(select max(sal) from emp where deptno=30);

#查询10号部门员工的部门名称,员工名称,工资(多表查询多条件)
select dept.dname, emp.ename, emp.sal from dept,emp where dept.deptno=emp.deptno and emp.deptno=10;

#查询员工姓名,工资,工资级别(between)
select a1.ename, a1.sal, a2.grade from emp a1, salgrade a2 where a1.sal between a2.losal and a2.hisal;
select emp.ename,emp.sal,salgrade.grade from emp,salgrade where emp.sal between salgrade.losal and salgrade.hisal;

ENAME             SAL      GRADE
---------- ---------- ----------
SMITH             800          1
JAMES             950          1
ADAMS            1100          1
WARD             1250          2
MARTIN           1250          2
MILLER           1300          2
TURNER           1500          3
ALLEN            1600          3
CLARK            2450          4
BLAKE            2850          4
JONES            2975          4
SCOTT            3000          4
FORD             3000          4
KING             5000          5


#显示雇员名,雇员工资及部门名字,并按照部门排序
select a1.ename,a1.sal,a2.dname from emp a1,dept a2 where a1.deptno=a2.deptno order by a2.dname;
select emp.ename,emp.sal,dept.dname from emp,dept where emp.deptno = dept.deptno order by dept.dname; 
ENAME             SAL DNAME
---------- ---------- --------------
MILLER           1300 ACCOUNTING
KING             5000 ACCOUNTING
CLARK            2450 ACCOUNTING
ADAMS            1100 RESEARCH
FORD             3000 RESEARCH
JONES            2975 RESEARCH
SMITH             800 RESEARCH
SCOTT            3000 RESEARCH
WARD             1250 SALES
TURNER           1500 SALES
ALLEN            1600 SALES
JAMES             950 SALES
BLAKE            2850 SALES
MARTIN           1250 SALES


#显示雇员名,雇员工资及部门名字,工资等级,并按照部门排序(三表查询)

select a1.ename, a1.sal, a2.dname, a3.grade from emp a1, dept a2, salgrade a3 where a1.deptno=a2.deptno and a1.sal between a3.losal and a3.hisal order by a2.dname;

select emp.ename, emp.sal, dept.dname, salgrade.grade from emp, dept, salgrade where emp.deptno=dept.deptno and emp.sal between salgrade.losal and salgrade.hisal order by dept.dname; 

#Fromat:
SELECT emp.ename, emp.sal, dept.dname, salgrade.grade
FROM emp, dept, salgrade
WHERE emp.deptno = dept.deptno
    AND emp.sal BETWEEN salgrade.losal AND salgrade.hisal
ORDER BY dept.dname;

ENAME             SAL DNAME               GRADE
---------- ---------- -------------- ----------
KING             5000 ACCOUNTING              5
MILLER           1300 ACCOUNTING              2
CLARK            2450 ACCOUNTING              4
ADAMS            1100 RESEARCH                1
JONES            2975 RESEARCH                4
SCOTT            3000 RESEARCH                4
SMITH             800 RESEARCH                1
FORD             3000 RESEARCH                4
JAMES             950 SALES                   1
MARTIN           1250 SALES                   2
WARD             1250 SALES                   2
TURNER           1500 SALES                   3
BLAKE            2850 SALES                   4
ALLEN            1600 SALES                   3


#不显示的字段可以用于排序
select a1.ename, a2.dname, a1.sal from emp a1, dept a2 where a1.deptno=a2.deptno order by a1.deptno ;

ENAME      DNAME                 SAL
---------- -------------- ----------
CLARK      ACCOUNTING           2450
KING       ACCOUNTING           5000
MILLER     ACCOUNTING           1300
JONES      RESEARCH             2975
FORD       RESEARCH             3000
ADAMS      RESEARCH             1100
SMITH      RESEARCH              800
SCOTT      RESEARCH             3000
WARD       SALES                1250
TURNER     SALES                1500
ALLEN      SALES                1600
JAMES      SALES                 950
BLAKE      SALES                2850
MARTIN     SALES                1250


#显示员工的领导
select a1.ename, a2.ename from emp a1, emp a2 where a1.mgr=a2.empno order by a2.ename;

ENAME      ENAME
---------- ----------
MARTIN     BLAKE
JAMES      BLAKE
WARD       BLAKE
ALLEN      BLAKE
TURNER     BLAKE
MILLER     CLARK
SMITH      FORD
SCOTT      JONES
FORD       JONES
CLARK      KING
JONES      KING
BLAKE      KING
ADAMS      SCOTT

#显示FORD的信息并且把mgr字段换为老板姓名

SELECT A1.EMPNO,A1.ENAME,A1.JOB,A2.ENAME AS "老板名字",A1.HIREDATE,A1.SAL,A1.COMM,A1.DEPTNO  FROM EMP A1, EMP A2 WHERE A1.MGR=A2.EMPNO AND A1.ENAME='FORD';

#Format:
SELECT A1.EMPNO, A1.ENAME, A1.JOB, A2.ENAME AS "老板名字", A1.HIREDATE
    , A1.SAL, A1.COMM, A1.DEPTNO
FROM EMP A1, EMP A2
WHERE A1.MGR = A2.EMPNO
    AND A1.ENAME = 'FORD';
    
     EMPNO ENAME      JOB       老板名字   HIREDATE                  SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------ ---------- ---------- ----------
      7902 FORD       ANALYST   JONES      03-DEC-81                3000                    20


##子查询
#单行子查询
#如何显示和SMITH同一部门的所有员工
SELECT * FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM EMP WHERE ENAME='SMITH');

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------ ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80                 800                    20
      7566 JONES      MANAGER         7839 02-APR-81                2975                    20
      7788 SCOTT      ANALYST         7566 19-APR-87                3000                    20
      7876 ADAMS      CLERK           7788 23-MAY-87                1100                    20
      7902 FORD       ANALYST         7566 03-DEC-81                3000                    20


#多行子查询
#如何查询和部门20号部门的工作相同的雇员的名字,岗位,工资和部门号
SELECT * FROM EMP WHERE JOB IN (SELECT DISTINCT JOB FROM EMP WHERE DEPTNO=20);

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------ ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80                 800                    20
      7876 ADAMS      CLERK           7788 23-MAY-87                1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81                 950                    30
      7934 MILLER     CLERK           7782 23-JAN-82                1300                    10
      7566 JONES      MANAGER         7839 02-APR-81                2975                    20
      7698 BLAKE      MANAGER         7839 01-MAY-81                2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81                2450                    10
      7788 SCOTT      ANALYST         7566 19-APR-87                3000                    20
      7902 FORD       ANALYST         7566 03-DEC-81                3000                    20

      
      

      
#显示工资比部门30的*所有*员工高的员工的姓名,工资和部门号

#TIPS: ALL 关键字, 100 > ALL(10,30,50,200,400,500) --> FALSE
#                   300 > ALL(10,30,50,200,400,500) --> FALSE
#                   600 > ALL(10,30,50,200,400,500) --> TRUE


SELECT ENAME,SAL,DEPTNO FROM EMP WHERE SAL > ALL(SELECT SAL FROM EMP WHERE DEPTNO=30) ORDER BY ENAME;

ENAME             SAL     DEPTNO
---------- ---------- ----------
FORD             3000         20
JONES            2975         20
KING             5000         10
SCOTT            3000         20

#Also: 这种写法个人觉得更好一些,可能效率更高一些
SELECT ENAME,SAL,DEPTNO FROM EMP WHERE SAL > (SELECT MAX(SAL) FROM EMP WHERE DEPTNO=30) ORDER BY ENAME ;

ENAME             SAL     DEPTNO
---------- ---------- ----------
FORD             3000         20
JONES            2975         20
KING             5000         10
SCOTT            3000         20

#显示工资比部门30的所有员工高的员工的姓名,工资和部门名称

SELECT A1.ENAME, A1.SAL, A2.DNAME FROM EMP A1, DEPT A2 WHERE A1.DEPTNO = A2.DEPTNO AND A1.SAL > (SELECT MAX(SAL) FROM EMP WHERE DEPTNO=30) ORDER BY A1.ENAME; 

#Format:
SELECT A1.ENAME, A1.SAL, A2.DNAME
FROM EMP A1, DEPT A2
WHERE A1.DEPTNO = A2.DEPTNO
    AND A1.SAL > (
        SELECT MAX(SAL)
        FROM EMP
        WHERE DEPTNO = 30
    )
ORDER BY A1.ENAME;


ENAME             SAL DNAME
---------- ---------- --------------
FORD             3000 RESEARCH
JONES            2975 RESEARCH
KING             5000 ACCOUNTING
SCOTT            3000 RESEARCH

#这两种写法哪种更好呢?个人觉得上一种更清晰。
SELECT A1.ENAME, A1.SAL, A2.DNAME FROM EMP A1, DEPT A2 WHERE A1.SAL > (SELECT MAX(SAL) FROM EMP WHERE DEPTNO=30) AND A1.DEPTNO=A2.DEPTNO ORDER BY A1.ENAME; 

#Format:
SELECT A1.ENAME, A1.SAL, A2.DNAME
FROM EMP A1, DEPT A2
WHERE A1.SAL > (
        SELECT MAX(SAL)
        FROM EMP
        WHERE DEPTNO = 30
    )
    AND A1.DEPTNO = A2.DEPTNO
ORDER BY A1.ENAME;

ENAME             SAL DNAME
---------- ---------- --------------
FORD             3000 RESEARCH
JONES            2975 RESEARCH
KING             5000 ACCOUNTING
SCOTT            3000 RESEARCH


#显示工资比部门30的*任意*员工高的员工的姓名,工资和部门号

#TIPS: ANY 关键字, 100 > ANY(10,30,50,200,400,500) --> TRUE
#                   300 > ANY(10,30,50,200,400,500) --> TRUE
#                   600 > ANY(10,30,50,200,400,500) --> TRUE
#                   5   > ANY(10,30,50,200,400,500) --> FALSE

SELECT ENAME,SAL,DEPTNO FROM EMP WHERE SAL > ANY(SELECT SAL FROM EMP WHERE DEPTNO=30) ORDER BY ENAME;

ENAME             SAL     DEPTNO
---------- ---------- ----------
ADAMS            1100         20
ALLEN            1600         30
BLAKE            2850         30
CLARK            2450         10
FORD             3000         20
JONES            2975         20
KING             5000         10
MARTIN           1250         30
MILLER           1300         10
SCOTT            3000         20
TURNER           1500         30
WARD             1250         30

#Also 效率高
SELECT ENAME,SAL,DEPTNO FROM EMP WHERE SAL > (SELECT MIN(SAL) FROM EMP WHERE DEPTNO=30) ORDER BY ENAME;

ENAME             SAL     DEPTNO
---------- ---------- ----------
ADAMS            1100         20
ALLEN            1600         30
BLAKE            2850         30
CLARK            2450         10
FORD             3000         20
JONES            2975         20
KING             5000         10
MARTIN           1250         30
MILLER           1300         10
SCOTT            3000         20
TURNER           1500         30
WARD             1250         30


#注解

SQL> SELECT ENAME,SAL,DEPTNO FROM EMP WHERE SAL > any(1000000,20) ORDER BY ENAME;

ENAME             SAL     DEPTNO
---------- ---------- ----------
ADAMS            1100         20
ALLEN            1600         30
BLAKE            2850         30
CLARK            2450         10
FORD             3000         20
JAMES             950         30
JONES            2975         20
KING             5000         10
MARTIN           1250         30
MILLER           1300         10
SCOTT            3000         20
SMITH             800         20
TURNER           1500         30
WARD             1250         30

14 rows selected.

Elapsed: 00:00:00.01
SQL> SELECT ENAME,SAL,DEPTNO FROM EMP WHERE SAL > all (1000000,20) ORDER BY ENAME;

no rows selected

Elapsed: 00:00:00.01


#复杂子查询(WHERE 多列值相同)
#查询与SMITH的部门和岗位完全相同的所有雇员
SELECT * FROM  EMP WHERE (DEPTNO, JOB) = ( SELECT DEPTNO, JOB FROM EMP WHERE ENAME = 'SMITH'); 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980-12-17        800                    20
      7876 ADAMS      CLERK           7788 1987-05-23       1100                    20
      
    

###重点   
###如何显示高于(自己部门平均工资)的员工信息(SMITH)
#TIP:
#查询出各个部门的平均工资和部门号

SELECT DEPTNO, AVG(SAL) MYSAL FROM EMP GROUP BY DEPTNO ; 

    DEPTNO      MYSAL
---------- ----------
        30 1566.66667
        20       2175
        10 2916.66667
        
#可以把上面的查询看做成一张子表,然后把两张表拼接在一起
#tip: 这里输出14个rows,使用了ROWNUM < 4 限制了输出条数
SELECT * FROM EMP A1, (SELECT DEPTNO, AVG(SAL) MYSAL FROM EMP GROUP BY DEPTNO) A2 WHERE A1.DEPTNO = A2.DEPTNO AND ROWNUM < 4;

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO     DEPTNO      MYSAL
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 1981-02-20       1600        300         30         30 1566.66667
      7521 WARD       SALESMAN        7698 1981-02-22       1250        500         30         30 1566.66667
      7654 MARTIN     SALESMAN        7698 1981-09-28       1250       1400         30         30 1566.66667

      
#最后在WHERE一下 A1.SAL > A2.MYSAL就ok了
SELECT A1.* FROM EMP A1, (SELECT DEPTNO, AVG(SAL) MYSAL FROM EMP GROUP BY DEPTNO) A2 WHERE A1.DEPTNO = A2.DEPTNO AND A1.SAL > A2.MYSAL;

#Format:
SELECT A1.*
FROM EMP A1, (
    SELECT DEPTNO, AVG(SAL) AS MYSAL
    FROM EMP
    GROUP BY DEPTNO
) A2
WHERE A1.DEPTNO = A2.DEPTNO
    AND A1.SAL > A2.MYSAL;

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO     DEPTNO      MYSAL
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 1981-02-20       1600        300         30         30 1566.66667
      7566 JONES      MANAGER         7839 1981-04-02       2975                    20         20       2175
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30         30 1566.66667
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20         20       2175
      7839 KING       PRESIDENT            1981-11-17       5000                    10         10 2916.66667
      7902 FORD       ANALYST         7566 1981-12-03       3000                    20         20       2175

#其他写法
SELECT A1.*, A2.AVGSAL
FROM EMP A1
    LEFT JOIN (
        SELECT DEPTNO, AVG(SAL) AS AVGSAL
        FROM EMP
        GROUP BY DEPTNO
    ) A2 ON A1.DEPTNO = A2.DEPTNO 
WHERE A1.SAL > A2.AVGSAL;

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO     AVGSAL
---------- ---------- --------- ---------- ------------------ ---------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 20-FEB-81                1600        300         30 1566.66667
      7566 JONES      MANAGER         7839 02-APR-81                2975                    20       2175
      7698 BLAKE      MANAGER         7839 01-MAY-81                2850                    30 1566.66667
      7788 SCOTT      ANALYST         7566 19-APR-87                3000                    20       2175
      7839 KING       PRESIDENT            17-NOV-81                5000                    10 2916.66667
      7902 FORD       ANALYST         7566 03-DEC-81                3000                    20       2175

6 rows selected.

#总结
#在from中使用子查询
#当在from子句中使用自查询时,该子查询会被作为一个视图来对待,因此叫作内嵌视图,
#当在from子句中使用查询时,必须给子查询指定别名。


##分页1 rownum
#TIP: ROWNUM是oracle的一个关键字,代表行号
#特别注意,ROWNUM只能使用一次,第二次使用将导致no rows selected
SELECT A1.*, ROWNUM FROM EMP A1 WHERE ROWNUM < 5 ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO     ROWNUM
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980-12-17        800                    20          1
      7499 ALLEN      SALESMAN        7698 1981-02-20       1600        300         30          2
      7521 WARD       SALESMAN        7698 1981-02-22       1250        500         30          3
      7566 JONES      MANAGER         7839 1981-04-02       2975                    20          4


#特别注意,ROWNUM只能使用一次,第二次使用将导致no rows selected
SELECT A1.*, ROWNUM FROM EMP A1 WHERE ROWNUM BETWEEN 5 AND 10 ; 

no rows selected

      
#二分查法1
SQL> SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1 WHERE ROWNUM < 10) WHERE RN > 5;

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30          6
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10          7
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20          8
      7839 KING       PRESIDENT            1981-11-17       5000                    10          9

#二分查法2,生成子视图
SQL> SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM (SELECT * FROM EMP) A1 WHERE ROWNUM < 10 ) WHERE RN > 5 ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30          6
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10          7
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20          8
      7839 KING       PRESIDENT            1981-11-17       5000                    10          9


      
####练习
#不知道为什么韩顺平老师讲的要二分查,但我个人认为这种查询方式比较好,可能二分查效率要高点?

SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1) WHERE RN BETWEEN 5 AND 10 ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 1981-09-28       1250       1400         30          5
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30          6
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10          7
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20          8
      7839 KING       PRESIDENT            1981-11-17       5000                    10          9
      7844 TURNER     SALESMAN        7698 1981-09-08       1500          0         30         10

#TIP 发现一个问题,如果需要排序怎么办?
#我考虑了下面语句
SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1 ORDER BY SAL) WHERE RN BETWEEN 5 AND 10 ; 
#但是这样显然不行,RN的顺序乱了,所以还是需要再嵌套一个子视图
SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1 ORDER BY SAL) WHERE RN BETWEEN 5 AND 10 ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 1981-09-28       1250       1400         30          5
      7844 TURNER     SALESMAN        7698 1981-09-08       1500          0         30         10
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10          7
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30          6
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20          8
      7839 KING       PRESIDENT            1981-11-17       5000                    10          9

#Like this
SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1 ORDER BY SAL) WHERE RN BETWEEN 5 AND 10 ;
#把FROM EMP A1 ORDER BY SAL --> FROM (SELECT * FROM ORDER BY SAL) A1
SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM (select * from emp order by sal) A1) WHERE RN BETWEEN 5 AND 10 ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 1981-09-28       1250       1400         30          5
      7934 MILLER     CLERK           7782 1982-01-23       1300                    10          6
      7844 TURNER     SALESMAN        7698 1981-09-08       1500          0         30          7
      7499 ALLEN      SALESMAN        7698 1981-02-20       1600        300         30          8
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10          9
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30         10
#这样的结果看起来才符合预期
      
      
      
#但是如果不做分组排序,那么下面这种形式也没什么问题
#显示奇数列  
SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1) WHERE MOD(RN,2) = 1;  

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980-12-17        800                    20          1
      7521 WARD       SALESMAN        7698 1981-02-22       1250        500         30          3
      7654 MARTIN     SALESMAN        7698 1981-09-28       1250       1400         30          5
      7782 CLARK      MANAGER         7839 1981-06-09       2450                    10          7
      7839 KING       PRESIDENT            1981-11-17       5000                    10          9
      7876 ADAMS      CLERK           7788 1987-05-23       1100                    20         11
      7902 FORD       ANALYST         7566 1981-12-03       3000                    20         13

#显示偶数列    
SELECT * FROM (SELECT A1.*, ROWNUM AS RN FROM EMP A1) WHERE MOD(RN,2) = 0 ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO         RN
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 1981-02-20       1600        300         30          2
      7566 JONES      MANAGER         7839 1981-04-02       2975                    20          4
      7698 BLAKE      MANAGER         7839 1981-05-01       2850                    30          6
      7788 SCOTT      ANALYST         7566 1987-04-19       3000                    20          8
      7844 TURNER     SALESMAN        7698 1981-09-08       1500          0         30         10
      7900 JAMES      CLERK           7698 1981-12-03        950                    30         12
      7934 MILLER     CLERK           7782 1982-01-23       1300                    10         14     


      
##分页2 rowid
tip: 待研究
##分页3 分析函数
tip: 待研究
      
      
#create new table from select

create table [newtablename] (newcolumns) as select (columns2) from [tablename]

#练习
CREATE TABLE EMP_DEPT (
    EMPNO,
    ENAME,
    JOB,
    MGR,
    MGRNAME,
    HIREDATE,
    SAL,
    COMM,
    DEPTNO,
    MGRDNAME
)
AS
SELECT A1.EMPNO, A1.ENAME, A1.JOB, A1.MGR, A3.ENAME
    , A1.HIREDATE, A1.SAL, A1.COMM, A1.DEPTNO, A2.DNAME
FROM EMP A1, DEPT A2, EMP A3
WHERE A1.DEPTNO = A2.DEPTNO
    AND A1.MGR = A3.EMPNO;

Table created.

SQL> SET LINESIZE 150
SQL> SELECT * FROM EMP_DEPT;

     EMPNO ENAME      JOB              MGR MGRNAME    HIREDATE          SAL       COMM     DEPTNO MGRDNAME
---------- ---------- --------- ---------- ---------- ---------- ---------- ---------- ---------- --------------
      7788 SCOTT      ANALYST         7566 JONES      1987-04-19       3000                    20 RESEARCH
      7902 FORD       ANALYST         7566 JONES      1981-12-03       3000                    20 RESEARCH
      7900 JAMES      CLERK           7698 BLAKE      1981-12-03        950                    30 SALES
      7499 ALLEN      SALESMAN        7698 BLAKE      1981-02-20       1600        300         30 SALES
      7654 MARTIN     SALESMAN        7698 BLAKE      1981-09-28       1250       1400         30 SALES
      7844 TURNER     SALESMAN        7698 BLAKE      1981-09-08       1500          0         30 SALES
      7521 WARD       SALESMAN        7698 BLAKE      1981-02-22       1250        500         30 SALES
      7934 MILLER     CLERK           7782 CLARK      1982-01-23       1300                    10 ACCOUNTING
      7876 ADAMS      CLERK           7788 SCOTT      1987-05-23       1100                    20 RESEARCH
      7782 CLARK      MANAGER         7839 KING       1981-06-09       2450                    10 ACCOUNTING
      7566 JONES      MANAGER         7839 KING       1981-04-02       2975                    20 RESEARCH
      7698 BLAKE      MANAGER         7839 KING       1981-05-01       2850                    30 SALES
      7369 SMITH      CLERK           7902 FORD       1980-12-17        800                    20 RESEARCH

13 rows selected.

#然而发现下面这位丢了,问题在于KING是BOSS,并没有MGR 导致 A1.MGR = A3.EMPNO --> FLASE

SQL> select * from emp where mgr is null ; 

     EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
      7839 KING       PRESIDENT            1981-11-17       5000                    10

Elapsed: 00:00:00.01  
      
      
#怎么解决???

#这个方法虽然实现了功能,但是觉得查询量很大,过于冗余
CREATE TABLE EMP_DEPT(EMPNO, ENAME, JOB, MGR, MGRNAME, HIREDATE, SAL, COMM, DEPTNO, MGRDNAME)
    AS 
    select A1.EMPNO,A1.ENAME,A1.JOB,A1.MGR,A3.ENAME,A1.HIREDATE,A1.SAL,A1.COMM,A1.DEPTNO,A2.DNAME from emp a1, dept a2, emp a3 where a1.deptno = a2.deptno and a1.mgr = a3.empno
    union ALL
    select A1.EMPNO,A1.ENAME,A1.JOB,null,null,A1.HIREDATE,A1.SAL,A1.COMM,A1.DEPTNO,A2.DNAME  from emp a1, dept a2  where a1.deptno = a2.deptno and a1.mgr is null;    

#Format:
CREATE TABLE EMP_DEPT (
    EMPNO,
    ENAME,
    JOB,
    MGR,
    MGRNAME,
    HIREDATE,
    SAL,
    COMM,
    DEPTNO,
    MGRDNAME
)
AS
SELECT A1.EMPNO, A1.ENAME, A1.JOB, A1.MGR, A3.ENAME
    , A1.HIREDATE, A1.SAL, A1.COMM, A1.DEPTNO, A2.DNAME
FROM emp a1, dept a2, emp a3
WHERE a1.deptno = a2.deptno
    AND a1.mgr = a3.empno
UNION ALL
SELECT A1.EMPNO, A1.ENAME, A1.JOB, NULL, NULL
    , A1.HIREDATE, A1.SAL, A1.COMM, A1.DEPTNO, A2.DNAME
FROM emp a1, dept a2
WHERE a1.deptno = a2.deptno
    AND a1.mgr IS NULL;
    

SQL> SELECT * FROM EMP_DEPT;

     EMPNO ENAME      JOB              MGR MGRNAME    HIREDATE                  SAL       COMM     DEPTNO MGRDNAME
---------- ---------- --------- ---------- ---------- ------------------ ---------- ---------- ---------- --------------
      7369 SMITH      CLERK           7902 FORD       17-DEC-80                 800                    20 RESEARCH
      7499 ALLEN      SALESMAN        7698 BLAKE      20-FEB-81                1600        300         30 SALES
      7521 WARD       SALESMAN        7698 BLAKE      22-FEB-81                1250        500         30 SALES
      7566 JONES      MANAGER         7839 KING       02-APR-81                2975                    20 RESEARCH
      7654 MARTIN     SALESMAN        7698 BLAKE      28-SEP-81                1250       1400         30 SALES
      7698 BLAKE      MANAGER         7839 KING       01-MAY-81                2850                    30 SALES
      7782 CLARK      MANAGER         7839 KING       09-JUN-81                2450                    10 ACCOUNTING
      7788 SCOTT      ANALYST         7566 JONES      19-APR-87                3000                    20 RESEARCH
      7839 KING       PRESIDENT                       17-NOV-81                5000                    10 ACCOUNTING
      7844 TURNER     SALESMAN        7698 BLAKE      08-SEP-81                1500          0         30 SALES
      7876 ADAMS      CLERK           7788 SCOTT      23-MAY-87                1100                    20 RESEARCH
      7900 JAMES      CLERK           7698 BLAKE      03-DEC-81                 950                    30 SALES
      7902 FORD       ANALYST         7566 JONES      03-DEC-81                3000                    20 RESEARCH
      7934 MILLER     CLERK           7782 CLARK      23-JAN-82                1300                    10 ACCOUNTING

14 rows selected.



#发现lefg/right/inner join可以满足

#tip:
#left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 
#right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
#inner join(等值连接) 只返回两个表中联结字段相等的行


#Copy了一下网上的资料
#表A记录如下:
#aID     aNum
#1     a20050111
#2     a20050112
#3     a20050113
#4     a20050114
#5     a20050115
#
#表B记录如下:
#bID     bName
#1     2006032401
#2     2006032402
#3     2006032403
#4     2006032404
#8     2006032408
#
#--------------------------------------------
#1.left join
#sql语句如下: 
#select * from A
#left join B 
#on A.aID = B.bID
#
#结果如下:
#aID     aNum     bID     bName
#1     a20050111    1     2006032401
#2     a20050112    2     2006032402
#3     a20050113    3     2006032403
#4     a20050114    4     2006032404
#5     a20050115    NULL     NULL
#
#(所影响的行数为 5 行)
#结果说明:
#left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的.
#换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID).
#B表记录不足的地方均为NULL.
#--------------------------------------------
#2.right join
#sql语句如下: 
#select * from A
#right join B 
#on A.aID = B.bID
#
#结果如下:
#aID     aNum     bID     bName
#1     a20050111    1     2006032401
#2     a20050112    2     2006032402
#3     a20050113    3     2006032403
#4     a20050114    4     2006032404
#NULL     NULL     8     2006032408
#
#(所影响的行数为 5 行)
#结果说明:
#仔细观察一下,就会发现,和left join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充.
#--------------------------------------------
#3.inner join
#sql语句如下: 
#select * from A
#innerjoin B 
#on A.aID = B.bID
#
#结果如下:
#aID     aNum     bID     bName
#1     a20050111    1     2006032401
#2     a20050112    2     2006032402
#3     a20050113    3     2006032403
#4     a20050114    4     2006032404
#
#结果说明:
#很明显,这里只显示出了 A.aID = B.bID的记录.这说明inner join并不以谁为基础,它只显示符合条件的记录.
#--------------------------------------------
#注: 
#LEFT JOIN操作用于在任何的 FROM 子句中,组合来源表的记录。
#使用 LEFT JOIN 运算来创建一个左边外部联接。
#左边外部联接将包含了从第一个(左边)开始的两个表中的全部记录,
#即使在第二个(右边)表中并没有相符值的记录。
#
#语法:FROM table1 LEFT JOIN table2 ON table1.field1 compopr table2.field2
#
#说明:table1, table2参数用于指定要将记录组合的表的名称。
#field1, field2参数指定被联接的字段的名称。且这些字段必须有相同的数据类型及包含相同类型的数据,但它们不需要有相同的名称。
#compopr参数指定关系比较运算符:"=", "<", ">", "<=", ">=" 或 "<>"。
#如果在INNER JOIN操作中要联接包含Memo 数据类型或 OLE Object 数据类型数据的字段,将会发生错误. 



#最后发现这个方法是比较满意的。
CREATE TABLE EMP_DEPT (
    EMPNO,
    ENAME,
    JOB,
    MGR,
    MGRNAME,
    HIREDATE,
    SAL,
    COMM,
    DEPTNO,
    MGRDNAME
)
AS
SELECT A1.EMPNO, A1.ENAME, A1.JOB, A1.MGR, A3.ENAME
    , A1.HIREDATE, A1.SAL, A1.COMM, A1.DEPTNO, A2.DNAME
FROM EMP A1
    LEFT JOIN DEPT A2 ON A1.DEPTNO = A2.DEPTNO
    LEFT JOIN EMP A3 ON A1.MGR = A3.EMPNO;
    
    
SQL> select * from emp_dept; 

     EMPNO ENAME      JOB              MGR MGRNAME    HIREDATE                  SAL       COMM     DEPTNO MGRDNAME
---------- ---------- --------- ---------- ---------- ------------------ ---------- ---------- ---------- --------------
      7788 SCOTT      ANALYST         7566 JONES      19-APR-87                3000                    20 RESEARCH
      7902 FORD       ANALYST         7566 JONES      03-DEC-81                3000                    20 RESEARCH
      7499 ALLEN      SALESMAN        7698 BLAKE      20-FEB-81                1600        300         30 SALES
      7521 WARD       SALESMAN        7698 BLAKE      22-FEB-81                1250        500         30 SALES
      7654 MARTIN     SALESMAN        7698 BLAKE      28-SEP-81                1250       1400         30 SALES
      7844 TURNER     SALESMAN        7698 BLAKE      08-SEP-81                1500          0         30 SALES
      7900 JAMES      CLERK           7698 BLAKE      03-DEC-81                 950                    30 SALES
      7934 MILLER     CLERK           7782 CLARK      23-JAN-82                1300                    10 ACCOUNTING
      7876 ADAMS      CLERK           7788 SCOTT      23-MAY-87                1100                    20 RESEARCH
      7782 CLARK      MANAGER         7839 KING       09-JUN-81                2450                    10 ACCOUNTING
      7566 JONES      MANAGER         7839 KING       02-APR-81                2975                    20 RESEARCH
      7698 BLAKE      MANAGER         7839 KING       01-MAY-81                2850                    30 SALES
      7369 SMITH      CLERK           7902 FORD       17-DEC-80                 800                    20 RESEARCH
      7839 KING       PRESIDENT                       17-NOV-81                5000                    10 ACCOUNTING

14 rows selected.


#UNION
#使用该操作符用于取得两个结果的并集,当使用该操作符时,会自动去掉结果中重复行。
SELECT ENAME, SAL, JOB FROM EMP WHERE SAL > 2500
    UNION
    SELECT ENAME, SAL, JOB FROM EMP WHERE JOB = 'MANAGER';

ENAME             SAL JOB
---------- ---------- ---------
BLAKE            2850 MANAGER
CLARK            2450 MANAGER
FORD             3000 ANALYST
JONES            2975 MANAGER
KING             5000 PRESIDENT
SCOTT            3000 ANALYST   



#解释:
SQL> SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE SAL > 2500; 

     EMPNO ENAME      JOB              SAL
---------- ---------- --------- ----------
      7566 JONES      MANAGER         2975
      7698 BLAKE      MANAGER         2850
      7788 SCOTT      ANALYST         3000
      7839 KING       PRESIDENT       5000
      7902 FORD       ANALYST         3000

SQL> SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE JOB = 'MANAGER';

     EMPNO ENAME      JOB              SAL
---------- ---------- --------- ----------
      7566 JONES      MANAGER         2975
      7698 BLAKE      MANAGER         2850
      7782 CLARK      MANAGER         2450
      
SQL> SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE SAL > 2500
  2  UNION
  3  SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE JOB = 'MANAGER';

     EMPNO ENAME      JOB              SAL
---------- ---------- --------- ----------
      7566 JONES      MANAGER         2975
      7698 BLAKE      MANAGER         2850
      7782 CLARK      MANAGER         2450
      7788 SCOTT      ANALYST         3000
      7839 KING       PRESIDENT       5000
      7902 FORD       ANALYST         3000

6 rows selected.


SQL> SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE SAL > 2500
  2  UNION ALL
  3  SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE JOB = 'MANAGER';

     EMPNO ENAME      JOB              SAL
---------- ---------- --------- ----------
      7566 JONES      MANAGER         2975
      7698 BLAKE      MANAGER         2850
      7788 SCOTT      ANALYST         3000
      7839 KING       PRESIDENT       5000
      7902 FORD       ANALYST         3000
      7566 JONES      MANAGER         2975
      7698 BLAKE      MANAGER         2850
      7782 CLARK      MANAGER         2450

8 rows selected.


#INTERSECT 取交集
SQL> 
SQL> SELECT * FROM TABLE1; 

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO     AVGSAL
---------- ---------- --------- ---------- ------------------ ---------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80                 800                    20          1
      7499 ALLEN      SALESMAN        7698 20-FEB-81                1600        300         30          2
      7521 WARD       SALESMAN        7698 22-FEB-81                1250        500         30          3
      7566 JONES      MANAGER         7839 02-APR-81                2975                    20          4
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30          5
      7698 BLAKE      MANAGER         7839 01-MAY-81                2850                    30          6

6 rows selected.

SQL> SELECT * FROM TABLE2; 

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO     AVGSAL
---------- ---------- --------- ---------- ------------------ ---------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30          5
      7698 BLAKE      MANAGER         7839 01-MAY-81                2850                    30          6
      7782 CLARK      MANAGER         7839 09-JUN-81                2450                    10          7
      7788 SCOTT      ANALYST         7566 19-APR-87                3000                    20          8
      7839 KING       PRESIDENT            17-NOV-81                5000                    10          9
      7844 TURNER     SALESMAN        7698 08-SEP-81                1500          0         30         10

6 rows selected.

SQL> SELECT * FROM TABLE1 INTERSECT SELECT * FROM TABLE2; 

     EMPNO ENAME      JOB              MGR HIREDATE                  SAL       COMM     DEPTNO     AVGSAL
---------- ---------- --------- ---------- ------------------ ---------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 28-SEP-81                1250       1400         30          5
      7698 BLAKE      MANAGER         7839 01-MAY-81                2850                    30          6
      
      
      









#更改当前session内的的日期格式
alter  session set nls_date_format = 'yy-mm-dd';
insert into student values(1,'小明','男','1997-12-11',1500);



#查看字符集
select userenv('language') from dual;
select * from nls_database_parameters;  #服务器字符集
select * from nls_instance_parameters;  #客户端字符集
select * from nls_database_parameters where parameter='NLS_CHARACTERSET';

#修改字符集
shutdown immediate
startup mount
alter system enable restricted session; #限制session
show parameter job_queue_processes; 
show parameter aq_tm_processes; 
alter system set job_queue_processes=0;
alter database open;
alter database character set ZHS16GBK;
#出现错误提示,新字符集必须是老字符集的超集,
#也就原来字符集是新字符集的子集,
#可以再Oracle官方文档上查询字符集包含关系。
#下面使用Oracle内部命令internal_use,跳过超集检查,
#生产环境不建议使用此方法。
alter database character set internal_use ZHS16GBK;
shutdown immediate;
startup;
#改完查一遍,然后改系统环境变量NLS_LANG,不然中文乱码
select * from nls_database_parameters where parameter='NLS_CHARACTERSET';



#删除数据
delete from [tablename]
#删表
drop table [tablename]
#快速删除(不写日志,无法找回)
truncate table [tablename]

你可能感兴趣的:(Oracle学习笔记-SELECT详解,数据库基本操作)