赞
踩
提示:
在一个SELECT语句中查询了两张或两张以上的表就是多表查询,也称作 多表联查 或 连接查询
笛卡尔积
m元关系R 和 m元关系S的笛卡尔积记为 R*S,结果是一个(n+m)列元组的集合,元组的前n列是关系R的一个元组,后m列是关系S的一个元组;计算时从R的第一个元组开始,依次与S的每一个元组组合
笛卡尔积对两个关系R和S进行操作,产生的关系中元组个数为两个关系中元组个数之积
笛卡尔积也叫连接查询,没有 on连接条件
select * from emp,temp ;
等值连接
select * from a join b on a.a1=b.b1 ;
自然连接
select * from a natural join b ;
区别
表的别名
定义
当查询结果中的所有数据都 满足连接条件时,就称该查询为 内连接(INNER JOIN)
SELECT 列名 ,...
FROM 表名 [INNER] JOIN 表名
ON 连接条件
[WHERE 筛选条件]
[GROUP BY 分组条件 [HAVING 筛选条件]]
[ORDER BY 排序条件] ;
两种写法
select * from c,p where c.course_id = p.course_id ;
select * from c inner join p on c.course_id = p.course_id ;
分类
等值连接
SELECT e.empno,e.ename,e.deptno, d.deptno,d.dname,d.loc
FROM emp e INNER JOIN dept d
ON e.deptno = d.deptno ;
非等值连接
SELECT e.empno,e.ename,e.sal, g.grade
FROM emp e INNER JOIN salgrade g
ON e.sal BETWEEN g.losal AND g.hisal ;
定义
当查询结果中除了 满足连接条件 数据外,也包含不满足连接条件的数据时,就称该查询为 外连接(OUTER JOIN)
SELECT 列名 ,...
FROM 表名 {LEFT|RIGHT|FULL} [OUTER] JOIN 表名
ON 连接条件
[WHERE 筛选条件]
[GROUP BY 分组条件 [HAVING 筛选条件]]
[ORDER BY 排序条件] ;
分类
左外连接
定义
语句
SELECT ... FROM 表名 LEFT [OUTER] JOIN 表名 ON 连接条件 ;
右外连接
定义
语句
SELECT ... FROM 表名 RIGHT [OUTER] JOIN 表名 ON 连接条件 ;
全外连接
定义
语句
SELECT ... FROM 表名 FULL [OUTER] JOIN 表名 ON 连接条件 ;
自关联
自连接
SELECT e.empno , e.ename , m.empno , m.ename FROM emp e JOIN emp m ON e.mgr = m.empno ;
purge 表示彻底删除该表而不是将该表删除到回收站(recyclebin)
DROP TABLE 表名 [ CASCADE CONSTRAINTS ] [PURGE] ;
查找两个表,此查询会先形成笛卡尔积
SELECT * FROM t_majors , t_courses ;
从以上的笛卡尔乘积中查找 专业 id 为 1001 的信息
SELECT * FROM t_majors , t_courses WHERE t_majors.id = 1001 ;
可以在 FROM 之后的 表名 之后 使用 空格 隔开,指定表的别名
ELECT * FROM t_majors m , t_courses c WHERE m.id = 1001 ;
仅列出 专业名称 和 课程名称
SELECT m.name , c.name FROM t_majors m , t_courses c WHERE m.id = 1001 ;
SQL> SQL> -- 创建两张简单的表 (每张表两个列) SQL> SQL> SQL> -- DROP TABLE 表名 [ CASCADE CONSTRAINTS ] [PURGE] ; SQL> DROP TABLE t_majors PURGE ; DROP TABLE t_majors PURGE * 第 1 行出现错误: ORA-02449: 表中的唯一/主键被外键引用 SQL> DROP TABLE t_majors PURGE CASCADE; DROP TABLE t_majors PURGE CASCADE * 第 1 行出现错误: ORA-00933: SQL 命令未正确结束 SQL> -- 需要先删除t_students表 SQL> DROP TABLE t_students PURGE ; 表已删除。 SQL> DROP TABLE t_majors PURGE ; 表已删除。 SQL> CREATE TABLE t_majors ( id NUMBER(5) , name VARCHAR2(20) ) ; 表已创建。 SQL> INSERT INTO t_majors VALUES ( 1001 , '软件工程' ); 已创建 1 行。 执行计划 ---------------------------------------------------------- ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | INSERT STATEMENT | | 1 | 100 | 1 (0)| 00:00:01 | | 1 | LOAD TABLE CONVENTIONAL | T_MAJORS | | | | | ------------------------------------------------------------------------------------- SQL> SET AUTOTRACE OFF SQL> INSERT INTO t_majors VALUES ( 2002 , '土木工程' ); 已创建 1 行。 SQL> INSERT INTO t_majors VALUES ( 3003 , '环境工程' ); 已创建 1 行。 SQL> commit ; 提交完成。 SQL> SELECT * FROM t_majors ; ID NAME ---------- -------------------- 1001 软件工程 2002 土木工程 3003 环境工程 SQL> SQL> CREATE TABLE t_courses ( id NUMBER(5) , name VARCHAR2(20) ) ; 表已创建。 SQL> INSERT INTO t_courses VALUES ( 9001 , 'Java' ); 已创建 1 行。 SQL> INSERT INTO t_courses VALUES ( 9002 , 'Database' ); 已创建 1 行。 SQL> INSERT INTO t_courses VALUES ( 2002 , 'HTML/CSS' ); 已创建 1 行。 SQL> INSERT INTO t_courses VALUES ( 9003 , 'JavaScript' ); 已创建 1 行。 SQL> commit ; 提交完成。 SQL> SELECT * FROM t_courses ; ID NAME ---------- -------------------- 9001 Java 9002 Database 2002 HTML/CSS 9003 JavaScript SQL> SELECT * FROM t_majors ; ID NAME ---------- -------------------- 1001 软件工程 2002 土木工程 3003 环境工程 SQL> SELECT * FROM t_majors , t_courses ; ID NAME ID NAME ---------- -------------------- ---------- -------------------- 1001 软件工程 9001 Java 1001 软件工程 9002 Database 1001 软件工程 2002 HTML/CSS 1001 软件工程 9003 JavaScript 2002 土木工程 9001 Java 2002 土木工程 9002 Database 2002 土木工程 2002 HTML/CSS 2002 土木工程 9003 JavaScript 3003 环境工程 9001 Java 3003 环境工程 9002 Database 3003 环境工程 2002 HTML/CSS ID NAME ID NAME ---------- -------------------- ---------- -------------------- 3003 环境工程 9003 JavaScript 已选择12行。 SQL> -- 从以上的笛卡尔乘积中查找 专业 id 为 1001 的信息 SQL> SELECT * FROM t_majors , t_courses WHERE id = 1001 ; SELECT * FROM t_majors , t_courses WHERE id = 1001 * 第 1 行出现错误: ORA-00918: 未明确定义列 SQL> SELECT * FROM t_majors , t_courses WHERE t_majors.id = 1001 ; ID NAME ID NAME ---------- -------------------- ---------- -------------------- 1001 软件工程 9001 Java 1001 软件工程 9002 Database 1001 软件工程 2002 HTML/CSS 1001 软件工程 9003 JavaScript SQL> -- 以上查询会先形成笛卡尔乘积,再从笛卡尔乘积中挑选 专业id 为 1001 的数据 SQL> SQL> -- 可以在 FROM 之后的 表名 之后 使用 空格 隔开,指定表的别名 SQL> SQL> SELECT * FROM t_majors m , t_courses c WHERE m.id = 1001 ; ID NAME ID NAME ---------- -------------------- ---------- -------------------- 1001 软件工程 9001 Java 1001 软件工程 9002 Database 1001 软件工程 2002 HTML/CSS 1001 软件工程 9003 JavaScript SQL> -- 仅列出 专业名称 和 课程名称 SQL> SELECT m.name , c.name FROM t_majors m , t_courses c WHERE m.id = 1001 ; NAME NAME -------------------- -------------------- 软件工程 Java 软件工程 Database 软件工程 HTML/CSS 软件工程 JavaScript SQL> spool off
查询 emp 表 和 dept 表 ( 因为屏幕大小有限,所以仅仅显示部分列即可 )
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc FROM emp e , dept d ;
先产生笛卡尔乘积,然后从笛卡尔乘积中筛选数据
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc
FROM emp e , dept d
WHERE e.deptno = d.deptno ;
以上查询的含义是: 查询每个员工的个人信息 及 其部门信息 ( 不统计没有部门的员工 和 没有员工的部门 )
由以上查询可知,如果从两张表中仅挑选满足 emp.deptno = dept.deptno
条件的数据,就可以不产生笛卡尔乘积
此时就可以将 emp.deptno = dept.deptno
当做 【连接条件】 来对待
实际上 deptno 可以是 dept 表的主键,emp 表中的 deptno 可以是个外键(它参照dept表的主键)
使用 标准 SQL 语句 实现 内连接查询
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc
FROM emp e
INNER JOIN dept d
ON e.deptno = d.deptno ;
此时已经不再产生笛卡尔乘积
其中的 INNER 关键字可以省略
查询 emp 表中 部门号 为 20 的雇员的个人信息 和 部门信息
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc
FROM emp e
JOIN dept d
ON e.deptno = d.deptno
WHERE e.deptno = 20 ;
查询 emp 表中 部门号 为 20 的雇员的个人信息 和 部门信息 ,并按照 工号进行降序排列
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc FROM emp e JOIN dept d ON e.deptno = d.deptno WHERE e.deptno = 20 ORDER BY empno DESC ; -- 以下写法与之前的写法有什么区别 (注意不单是写法上的区别) -- 将 e.deptno = 20 写在 ON e.deptno = d.deptno 之后 与 写在单独的 WHERE 子句之后有什么区别? SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc FROM emp e JOIN dept d ON e.deptno = d.deptno AND e.deptno = 20 ORDER BY empno DESC ; -- 解答:第一种写在where后,是将两个表进行内连接之后的结果集先按e.deptno=20的条件进行筛选,之后在select选择要列出的列并按empno降序排序 -- 第二种写在where前,是在两个表进行内连接时就先按e.deptno=20的条件连接两个表,得到结果集,之后在select选择要列出的列并按empno降序排序
查询emp表中所有雇员的个人信息和部门信息,如果某些雇员没有部门,也将其列在查询结果中
-- 左外连接:在 查询结果中 包含 join 关键字之前的表中不满足连接条件的数据
-- 即两个表进行左外连接后的结果集,包含左侧表中不满足 on连接条件的数,此时对应右侧表的数据为空
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc
FROM emp e LEFT OUTER JOIN dept d
ON e.deptno = d.deptno ;
查询emp表中所有雇员的个人信息和部门信息,如果某些部门没有员工,也将其列在查询结果中
-- 右外连接:在 查询结果中 包含 join 关键字之后的表中不满足连接条件的数据
-- 即两个表进行右外连接后的结果集,包含右侧表中不满足 on连接条件的数,此时对应左侧表的数据为空
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno ;
全连接 ( Oracle 支持 ,MySQL 不支持 )
-- 全连接:先列出join左边表不满足结果条件,再列出join右边表不满足条件的结果
SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc
FROM emp e FULL OUTER JOIN dept d
ON e.deptno = d.deptno ;
内连接-非等值连接:查 emp 表中每个雇员的工号、姓名、薪水、薪水级别
SELECT e.empno , e.ename , e.sal , g.grade
FROM emp e JOIN salgrade g
ON e.sal BETWEEN g.losal AND g.hisal ;
SQL> -- 查看 emp 表结构 SQL> DESC emp ; 名称 是否为空? 类型 ----------------------------------------------------------------- -------- -------------------------------------------- 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> -- 查看 dept 表结构 SQL> DESC dept ; 名称 是否为空? 类型 ----------------------------------------------------------------- -------- -------------------------------------------- DEPTNO NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13) SQL> -- 查看 emp 表中的数据 SQL> SET linesize 120 ; SQL> SELECT * FROM emp ; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-12月-80 800 20 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7788 SCOTT ANALYST 7566 09-12月-82 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7876 ADAMS CLERK 7788 12-1月 -83 1100 20 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ---------- ---------- ---------- 7900 JAMES CLERK 7698 03-12月-81 950 30 7902 FORD ANALYST 7566 03-12月-81 3000 20 7934 MILLER CLERK 7782 23-1月 -82 1300 10 9257 HUA'AN CLERK 7839 23-1月 -85 1300 8526 QIU'XIANG ANALYST 7839 23-1月 -85 1400 已选择16行。 SQL> -- 查看 dept 表中的数据 SQL> SELECT * FROM dept ; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> SQL> -- 查询 emp 表 和 dept 表 ( 因为屏幕大小有限,所以仅仅显示部分列即可 ) SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e , dept d ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 10 ACCOUNTING NEW YORK 7499 ALLEN 30 10 ACCOUNTING NEW YORK 7521 WARD 30 10 ACCOUNTING NEW YORK 7566 JONES 20 10 ACCOUNTING NEW YORK 7654 MARTIN 30 10 ACCOUNTING NEW YORK 7698 BLAKE 30 10 ACCOUNTING NEW YORK 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 10 ACCOUNTING NEW YORK 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 10 ACCOUNTING NEW YORK 7876 ADAMS 20 10 ACCOUNTING NEW YORK EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7900 JAMES 30 10 ACCOUNTING NEW YORK 7902 FORD 20 10 ACCOUNTING NEW YORK 7934 MILLER 10 10 ACCOUNTING NEW YORK 9257 HUA'AN 10 ACCOUNTING NEW YORK 8526 QIU'XIANG 10 ACCOUNTING NEW YORK 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 20 RESEARCH DALLAS 7521 WARD 30 20 RESEARCH DALLAS 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 20 RESEARCH DALLAS 7698 BLAKE 30 20 RESEARCH DALLAS EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7782 CLARK 10 20 RESEARCH DALLAS 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 20 RESEARCH DALLAS 7844 TURNER 30 20 RESEARCH DALLAS 7876 ADAMS 20 20 RESEARCH DALLAS 7900 JAMES 30 20 RESEARCH DALLAS 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 20 RESEARCH DALLAS 9257 HUA'AN 20 RESEARCH DALLAS 8526 QIU'XIANG 20 RESEARCH DALLAS 7369 SMITH 20 30 SALES CHICAGO EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 30 SALES CHICAGO 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 30 SALES CHICAGO 7788 SCOTT 20 30 SALES CHICAGO 7839 KING 10 30 SALES CHICAGO 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 30 SALES CHICAGO 7900 JAMES 30 30 SALES CHICAGO EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7902 FORD 20 30 SALES CHICAGO 7934 MILLER 10 30 SALES CHICAGO 9257 HUA'AN 30 SALES CHICAGO 8526 QIU'XIANG 30 SALES CHICAGO 7369 SMITH 20 40 OPERATIONS BOSTON 7499 ALLEN 30 40 OPERATIONS BOSTON 7521 WARD 30 40 OPERATIONS BOSTON 7566 JONES 20 40 OPERATIONS BOSTON 7654 MARTIN 30 40 OPERATIONS BOSTON 7698 BLAKE 30 40 OPERATIONS BOSTON 7782 CLARK 10 40 OPERATIONS BOSTON EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7788 SCOTT 20 40 OPERATIONS BOSTON 7839 KING 10 40 OPERATIONS BOSTON 7844 TURNER 30 40 OPERATIONS BOSTON 7876 ADAMS 20 40 OPERATIONS BOSTON 7900 JAMES 30 40 OPERATIONS BOSTON 7902 FORD 20 40 OPERATIONS BOSTON 7934 MILLER 10 40 OPERATIONS BOSTON 9257 HUA'AN 40 OPERATIONS BOSTON 8526 QIU'XIANG 40 OPERATIONS BOSTON 已选择64行。 SQL> -- 先产生笛卡尔乘积,然后从笛卡尔乘积中筛选数据 SQL> SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e , dept d 3 WHERE e.deptno = d.deptno ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 20 RESEARCH DALLAS EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7900 JAMES 30 30 SALES CHICAGO 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 10 ACCOUNTING NEW YORK 已选择14行。 SQL> -- 以上查询的含义是: 查询每个员工的个人信息 及 其部门信息 ( 不统计没有部门的员工 和 没有员工的部门 ) SQL> SQL> -- 由以上查询可知,如果从两张表中仅挑选满足 emp.deptno = dept.deptno 条件的数据,就可以不产生笛卡尔乘积 SQL> SQL> -- 此时就可以将 emp.deptno = dept.deptno 当做 【连接条件】 来对待 SQL> SQL> -- 实际上 deptno 可以是 dept 表的主键,emp 表中的 deptno 可以是个外键(它参照dept表的主键) SQL> SQL> -- 使用 标准 SQL 语句 实现 内连接查询 SQL> SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e 3 INNER JOIN dept d 4 ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 20 RESEARCH DALLAS EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7900 JAMES 30 30 SALES CHICAGO 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 10 ACCOUNTING NEW YORK 已选择14行。 SQL> -- 此时已经不再产生笛卡尔乘积 SQL> SQL> -- 其中的 INNER 关键字可以省略 SQL> SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e 3 JOIN dept d 4 ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 20 RESEARCH DALLAS EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7900 JAMES 30 30 SALES CHICAGO 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 10 ACCOUNTING NEW YORK 已选择14行。 SQL> -- 查询 emp 表中 部门号 为 20 的雇员的个人信息 和 部门信息 SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e 3 JOIN dept d 4 ON e.deptno = d.deptno 5 WHERE e.deptno = 20 ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7566 JONES 20 20 RESEARCH DALLAS 7788 SCOTT 20 20 RESEARCH DALLAS 7876 ADAMS 20 20 RESEARCH DALLAS 7902 FORD 20 20 RESEARCH DALLAS SQL> -- 查询 emp 表中 部门号 为 20 的雇员的个人信息 和 部门信息 ,并按照 工号进行降序排列 SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e 3 JOIN dept d 4 ON e.deptno = d.deptno 5 WHERE e.deptno = 20 6 ORDER BY empno DESC ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7902 FORD 20 20 RESEARCH DALLAS 7876 ADAMS 20 20 RESEARCH DALLAS 7788 SCOTT 20 20 RESEARCH DALLAS 7566 JONES 20 20 RESEARCH DALLAS 7369 SMITH 20 20 RESEARCH DALLAS SQL> SQL> SQL> -- 以下写法与之前的写法有什么区别 (注意不单是写法上的区别) SQL> SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 F 3 ; * 第 3 行出现错误: ORA-00923: 未找到要求的 FROM 关键字 SQL> ed 已写入 file afiedt.buf 1 SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e 3 JOIN dept d 4 ON e.deptno = d.deptno AND e.deptno = 20 5* ORDER BY empno DESC SQL> / EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7902 FORD 20 20 RESEARCH DALLAS 7876 ADAMS 20 20 RESEARCH DALLAS 7788 SCOTT 20 20 RESEARCH DALLAS 7566 JONES 20 20 RESEARCH DALLAS 7369 SMITH 20 20 RESEARCH DALLAS SQL> -- 将 e.deptno = 20 写在 ON e.deptno = d.deptno 之后 与 写在单独的 WHERE 子句之后有什么区别? SQL> SQL> SQL> -- 在 查询结果中 包含 join 关键字之前的表中不满足连接条件的数据 SQL> SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e LEFT OUTER JOIN dept d 3 ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7934 MILLER 10 10 ACCOUNTING NEW YORK 7839 KING 10 10 ACCOUNTING NEW YORK 7782 CLARK 10 10 ACCOUNTING NEW YORK 7902 FORD 20 20 RESEARCH DALLAS 7876 ADAMS 20 20 RESEARCH DALLAS 7788 SCOTT 20 20 RESEARCH DALLAS 7566 JONES 20 20 RESEARCH DALLAS 7369 SMITH 20 20 RESEARCH DALLAS 7900 JAMES 30 30 SALES CHICAGO 7844 TURNER 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7654 MARTIN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7499 ALLEN 30 30 SALES CHICAGO 8526 QIU'XIANG 9257 HUA'AN 已选择16行。 SQL> -- 以上查询就是左外连接的结果 SQL> -- 以上查询的含义是: SQL> -- 查询emp表中所有雇员的个人信息和部门信息,如果某些雇员没有部门,也将其列在查询结果中 SQL> SQL> SQL> -- 在 查询结果中 包含 join 关键字之后的表中不满足连接条件的数据 SQL> SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e RIGHT OUTER JOIN dept d 3 ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 20 RESEARCH DALLAS EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7900 JAMES 30 30 SALES CHICAGO 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 10 ACCOUNTING NEW YORK 40 OPERATIONS BOSTON 已选择15行。 SQL> SQL> SQL> SQL> -- 全连接 ( Oracle 支持 ,MySQL 不支持 ) SQL> -- 先列出左边不满足的结果,再列出右边不满足条件的结果 SQL> SELECT e.empno , e.ename , e.deptno , d.deptno , d.dname , d.loc 2 FROM emp e FULL OUTER JOIN dept d 3 ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7369 SMITH 20 20 RESEARCH DALLAS 7499 ALLEN 30 30 SALES CHICAGO 7521 WARD 30 30 SALES CHICAGO 7566 JONES 20 20 RESEARCH DALLAS 7654 MARTIN 30 30 SALES CHICAGO 7698 BLAKE 30 30 SALES CHICAGO 7782 CLARK 10 10 ACCOUNTING NEW YORK 7788 SCOTT 20 20 RESEARCH DALLAS 7839 KING 10 10 ACCOUNTING NEW YORK 7844 TURNER 30 30 SALES CHICAGO 7876 ADAMS 20 20 RESEARCH DALLAS EMPNO ENAME DEPTNO DEPTNO DNAME LOC ---------- ---------- ---------- ---------- -------------- ------------- 7900 JAMES 30 30 SALES CHICAGO 7902 FORD 20 20 RESEARCH DALLAS 7934 MILLER 10 10 ACCOUNTING NEW YORK 9257 HUA'AN 8526 QIU'XIANG 40 OPERATIONS BOSTON 已选择17行。 SQL> SQL> SQL> SQL> SQL> SQL> SQL> -- 最后,尝试查询 emp 表中每个雇员的工号、姓名、薪水、薪水级别 SQL> SQL> DESE salgrade ; SP2-0734: 未知的命令开头 "DESE salgr..." - 忽略了剩余的行。 SQL> DESC salgrade ; 名称 是否为空? 类型 ----------------------------------------------------------------- -------- -------------------------------------------- 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 SQL> SELECT e.empno , e.ename , e.sal , g.grade 2 FROM emp e 3 JOIN salgrade g 4 ON e.sal BETWEEN g.losal AND g.hisal ; EMPNO ENAME SAL GRADE ---------- ---------- ---------- ---------- 7369 SMITH 800 1 7900 JAMES 950 1 7876 ADAMS 1100 1 7521 WARD 1250 2 7654 MARTIN 1250 2 7934 MILLER 1300 2 9257 HUA'AN 1300 2 8526 QIU'XIANG 1400 2 7844 TURNER 1500 3 7499 ALLEN 1600 3 7782 CLARK 2450 4 EMPNO ENAME SAL GRADE ---------- ---------- ---------- ---------- 7698 BLAKE 2850 4 7566 JONES 2975 4 7788 SCOTT 3000 4 7902 FORD 3000 4 7839 KING 5000 5 已选择16行。 SQL> spool off
-- linesize SET linesize 150 ; -- user_objects COLUMN object_name FORMAT a20 ; -- user_cons_columns / user_constraints COLUMN table_name FORMAT a20 ; COLUMN column_name FORMAT a20 ; COLUMN constraint_name FORMAT a30 ; COLUMN owner FORMAT a10 ; -- s_emp : first_name / last_name / title / comments COLUMN first_name FORMAT a15 ; COLUMN last_name FORMAT a15 ; COLUMN title FORMAT a15 ; COLUMN comments FORMAT a10 ; COLUMN id FORMAT 99 ; COLUMN manager_id FORMAT 99 ; -- id列为数值类型,设置格式用数字 COLUMN dept_id FORMAT 99 ; -- format 00代表两位数,不足时补0;format 99 代表两位数,不足时不补0
统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区,不统计部门号为空的雇员,也不统计没有员工的部门
SELECT e.empno , e.ename , e.job ,e.sal , d.dname , d.loc FROM emp e JOIN dept d
ON e.deptno = d.deptno ;
统计薪水级别不低于3的雇员信息 ( 列出它们的 工号、姓名、岗位、月薪 、薪水级别 )
SELECT e.empno , e.ename , e.job , e.sal , g.grade
FROM emp e INNER JOIN salgrade g
ON e.sal BETWEEN g.losal AND g.hisal
WHERE g.grade >=3 ;
-- 或者写为
SELECT e.empno , e.ename , e.job , e.sal , g.grade
FROM emp e INNER JOIN salgrade g
ON e.sal BETWEEN g.losal AND g.hisal AND g.grade >=3 ;
统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区,如果某位雇员部门号为空,也将该雇员的信息显示在查询结果中
SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc
FROM emp e LEFT OUTER JOIN dept d
ON e.deptno = d.deptno ;
统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区,如果某个部门没有员工,也将该部门的信息显示在查询结果中
SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno ;
统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区
如果某位雇员部门号为空,也将该雇员的信息显示在查询结果中
如果某个部门没有员工,也将该部门的信息显示在查询结果中
SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc
FROM emp e FULL OUTER JOIN dept d
ON e.deptno = d.deptno ;
统计每个员工的姓( last_name ) 、名 ( first_name ) 、部门名称、地区名称
SELECT e.last_name , e.first_name , d.name , r.name
FROM s_emp e JOIN s_dept d ON e.dept_id = d.id
JOIN s_region r ON d.region_id = r.id ;
以上SQL建议每天手敲/手抄三遍( 早、上午或下午、晚上 )
SQL> -- 内连接 SQL> SQL> -- 统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区 SQL> -- 不统计部门号为空的雇员,也不统计没有员工的部门 SQL> SQL> DESC emp ; 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- 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> DESC dept ; 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- DEPTNO NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13) SQL> SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc 2 FROM emp e INNER JOIN dept d ON e.deptno = d.deptno ; EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7369 SMITH CLERK 800 RESEARCH DALLAS 7499 ALLEN SALESMAN 1600 SALES CHICAGO 7521 WARD SALESMAN 1250 SALES CHICAGO 7566 JONES MANAGER 2975 RESEARCH DALLAS 7654 MARTIN SALESMAN 1250 SALES CHICAGO 7698 BLAKE MANAGER 2850 SALES CHICAGO 7782 CLARK MANAGER 2450 ACCOUNTING NEW YORK 7788 SCOTT ANALYST 3000 RESEARCH DALLAS 7839 KING PRESIDENT 5000 ACCOUNTING NEW YORK 7844 TURNER SALESMAN 1500 SALES CHICAGO 7876 ADAMS CLERK 1100 RESEARCH DALLAS EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7900 JAMES CLERK 950 SALES CHICAGO 7902 FORD ANALYST 3000 RESEARCH DALLAS 7934 MILLER CLERK 1300 ACCOUNTING NEW YORK 已选择14行。 SQL> SQL> -- 统计薪水级别不低于3的雇员信息 ( 列出它们的 工号、姓名、岗位、月薪 、薪水级别 ) SQL> SQL> DESC salgrade ; 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- GRADE NUMBER LOSAL NUMBER HISAL NUMBER SQL> SELECT e.empno , e.ename , e.job , e.sal , g.grade 2 FROM emp e INNER JOIN salgrade g ON e.sal BETWEEN g.losal AND g.hisal 3 WHERE g.grade >= 3 ; EMPNO ENAME JOB SAL GRADE ---------- ---------- --------- ---------- ---------- 7844 TURNER SALESMAN 1500 3 7499 ALLEN SALESMAN 1600 3 7782 CLARK MANAGER 2450 4 7698 BLAKE MANAGER 2850 4 7566 JONES MANAGER 2975 4 7788 SCOTT ANALYST 3000 4 7902 FORD ANALYST 3000 4 7839 KING PRESIDENT 5000 5 已选择8行。 SQL> SELECT e.empno , e.ename , e.job , e.sal , g.grade 2 FROM emp e INNER JOIN salgrade g 3 ON e.sal BETWEEN g.losal AND g.hisal AND g.grade > 3 ; EMPNO ENAME JOB SAL GRADE ---------- ---------- --------- ---------- ---------- 7782 CLARK MANAGER 2450 4 7698 BLAKE MANAGER 2850 4 7566 JONES MANAGER 2975 4 7788 SCOTT ANALYST 3000 4 7902 FORD ANALYST 3000 4 7839 KING PRESIDENT 5000 5 已选择6行。 SQL> SQL> -- 外连接 SQL> SQL> -- 统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区 SQL> -- 如果某位雇员部门号为空,也将该雇员的信息显示在查询结果中 SQL> SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc 2 FROM emp e 3 LEFT OUTER JOIN dept d 4 ON e.deptno = d.deptno ; EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7934 MILLER CLERK 1300 ACCOUNTING NEW YORK 7839 KING PRESIDENT 5000 ACCOUNTING NEW YORK 7782 CLARK MANAGER 2450 ACCOUNTING NEW YORK 7902 FORD ANALYST 3000 RESEARCH DALLAS 7876 ADAMS CLERK 1100 RESEARCH DALLAS 7788 SCOTT ANALYST 3000 RESEARCH DALLAS 7566 JONES MANAGER 2975 RESEARCH DALLAS 7369 SMITH CLERK 800 RESEARCH DALLAS 7900 JAMES CLERK 950 SALES CHICAGO 7844 TURNER SALESMAN 1500 SALES CHICAGO 7698 BLAKE MANAGER 2850 SALES CHICAGO EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7654 MARTIN SALESMAN 1250 SALES CHICAGO 7521 WARD SALESMAN 1250 SALES CHICAGO 7499 ALLEN SALESMAN 1600 SALES CHICAGO 8526 QIU'XIANG ANALYST 1400 9257 HUA'AN CLERK 1300 已选择16行。 SQL> SQL> -- 统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区 SQL> -- 如果某个部门没有员工,也将该部门的信息显示在查询结果中 SQL> SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc 2 FROM emp e 3 RIGHT OUTER JOIN dept d 4 ON e.deptno = d.deptno ; EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7369 SMITH CLERK 800 RESEARCH DALLAS 7499 ALLEN SALESMAN 1600 SALES CHICAGO 7521 WARD SALESMAN 1250 SALES CHICAGO 7566 JONES MANAGER 2975 RESEARCH DALLAS 7654 MARTIN SALESMAN 1250 SALES CHICAGO 7698 BLAKE MANAGER 2850 SALES CHICAGO 7782 CLARK MANAGER 2450 ACCOUNTING NEW YORK 7788 SCOTT ANALYST 3000 RESEARCH DALLAS 7839 KING PRESIDENT 5000 ACCOUNTING NEW YORK 7844 TURNER SALESMAN 1500 SALES CHICAGO 7876 ADAMS CLERK 1100 RESEARCH DALLAS EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7900 JAMES CLERK 950 SALES CHICAGO 7902 FORD ANALYST 3000 RESEARCH DALLAS 7934 MILLER CLERK 1300 ACCOUNTING NEW YORK OPERATIONS BOSTON 已选择15行。 SQL> SQL> SQL> -- 统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区 SQL> -- 如果某位雇员部门号为空,也将该雇员的信息显示在查询结果中 SQL> -- 如果某个部门没有员工,也将该部门的信息显示在查询结果中 SQL> SQL> SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc 2 FROM emp e 3 FULL OUTER JOIN dept d 4 ON e.deptno = d.deptno ; EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7369 SMITH CLERK 800 RESEARCH DALLAS 7499 ALLEN SALESMAN 1600 SALES CHICAGO 7521 WARD SALESMAN 1250 SALES CHICAGO 7566 JONES MANAGER 2975 RESEARCH DALLAS 7654 MARTIN SALESMAN 1250 SALES CHICAGO 7698 BLAKE MANAGER 2850 SALES CHICAGO 7782 CLARK MANAGER 2450 ACCOUNTING NEW YORK 7788 SCOTT ANALYST 3000 RESEARCH DALLAS 7839 KING PRESIDENT 5000 ACCOUNTING NEW YORK 7844 TURNER SALESMAN 1500 SALES CHICAGO 7876 ADAMS CLERK 1100 RESEARCH DALLAS EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7900 JAMES CLERK 950 SALES CHICAGO 7902 FORD ANALYST 3000 RESEARCH DALLAS 7934 MILLER CLERK 1300 ACCOUNTING NEW YORK 9257 HUA'AN CLERK 1300 8526 QIU'XIANG ANALYST 1400 OPERATIONS BOSTON 已选择17行。 SQL> SQL> SQL> -- 以上SQL建议每天手敲/手抄三遍( 早、上午或下午、晚上 ) SQL> -- 要去想,去思考 SQL> SQL> SQL> SQL> -- 统计每位雇员的 工号、姓名、岗位、月薪、部门名称、部门所在地区 SQL> -- 如果某位雇员部门号为空,也将该雇员的信息显示在查询结果中 SQL> -- 使用右外连接完成 SQL> SQL> SELECT e.empno , e.ename , e.job , e.sal , d.dname , d.loc 2 FROM dept d RIGHT OUTER JOIN emp e ON e.deptno = d.deptno ; EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7934 MILLER CLERK 1300 ACCOUNTING NEW YORK 7839 KING PRESIDENT 5000 ACCOUNTING NEW YORK 7782 CLARK MANAGER 2450 ACCOUNTING NEW YORK 7902 FORD ANALYST 3000 RESEARCH DALLAS 7876 ADAMS CLERK 1100 RESEARCH DALLAS 7788 SCOTT ANALYST 3000 RESEARCH DALLAS 7566 JONES MANAGER 2975 RESEARCH DALLAS 7369 SMITH CLERK 800 RESEARCH DALLAS 7900 JAMES CLERK 950 SALES CHICAGO 7844 TURNER SALESMAN 1500 SALES CHICAGO 7698 BLAKE MANAGER 2850 SALES CHICAGO EMPNO ENAME JOB SAL DNAME LOC ---------- ---------- --------- ---------- -------------- ------------- 7654 MARTIN SALESMAN 1250 SALES CHICAGO 7521 WARD SALESMAN 1250 SALES CHICAGO 7499 ALLEN SALESMAN 1600 SALES CHICAGO 8526 QIU'XIANG ANALYST 1400 9257 HUA'AN CLERK 1300 已选择16行。 SQL> SQL> SQL> SQL> SQL> DESC s_emp ; 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER(7) LAST_NAME NOT NULL VARCHAR2(25) FIRST_NAME VARCHAR2(25) USERID VARCHAR2(8) START_DATE DATE COMMENTS VARCHAR2(255) MANAGER_ID NUMBER(7) TITLE VARCHAR2(25) DEPT_ID NUMBER(7) SALARY NUMBER(11,2) COMMISSION_PCT NUMBER(4,2) SQL> DESC s_dept ; 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER(7) NAME NOT NULL VARCHAR2(25) REGION_ID NUMBER(7) SQL> DESC s_region 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER(7) NAME NOT NULL VARCHAR2(50) SQL> -- 统计每个员工的姓( last_name ) 、名 ( first_name ) 、部门名称、地区名称 SQL> SQL> SELECT e.last_name , e.first_name , d.name , r.name 2 FROM s_emp e JOIN s_dept d ON e.dept_id = d.id 3 JOIN s_region r ON d.region_id = r.id ; LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Velasquez Carmen Administration North America Ngao LaDoris Operations North America Nagayama Midori Sales North America LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Quick-To-See Mark Finance North America Ropeburn Audry Administration North America Urguhart Molly Operations North America LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Menchu Roberta Operations South America Biri Ben Operations Africa / Middle East Catchpole Antoinette Operations Asia LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Havel Marta Operations Europe Magee Colin Sales North America Giljum Henry Sales South America LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Sedeghi Yasmin Sales Africa / Middle East Nguyen Mai Sales Asia Dumas Andre Sales Europe LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Maduro Elena Operations North America Smith George Operations North America Nozaki Akira Operations South America LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Patel Vikram Operations South America Newman Chad Operations Africa / Middle East 3karian Alexander Operations Africa / Middle East LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Chang Eddie Operations Asia Patel Radha Sales Asia Dancs Bela Operations Europe LAST_NAME FIRST_NAME NAME ------------------------- ------------------------- ------------------------- NAME -------------------------------------------------- Schwartz Sylvie Operations Europe 已选择25行。 SQL> column first_name format a20 ; SQL> column last_name format a20 ; SQL> column name format a20 ; SQL> set linesize 120 ; SQL> SELECT e.last_name , e.first_name , d.name , r.name 2 FROM s_emp e 3 JOIN s_dept d ON e.dept_id = d.id 4 JOIN s_region r ON d.region_id = r.id ; LAST_NAME FIRST_NAME NAME NAME -------------------- -------------------- -------------------- -------------------- Velasquez Carmen Administration North America Ngao LaDoris Operations North America Nagayama Midori Sales North America Quick-To-See Mark Finance North America Ropeburn Audry Administration North America Urguhart Molly Operations North America Menchu Roberta Operations South America Biri Ben Operations Africa / Middle East Catchpole Antoinette Operations Asia Havel Marta Operations Europe Magee Colin Sales North America LAST_NAME FIRST_NAME NAME NAME -------------------- -------------------- -------------------- -------------------- Giljum Henry Sales South America Sedeghi Yasmin Sales Africa / Middle East Nguyen Mai Sales Asia Dumas Andre Sales Europe Maduro Elena Operations North America Smith George Operations North America Nozaki Akira Operations South America Patel Vikram Operations South America Newman Chad Operations Africa / Middle East 3karian Alexander Operations Africa / Middle East Chang Eddie Operations Asia LAST_NAME FIRST_NAME NAME NAME -------------------- -------------------- -------------------- -------------------- Patel Radha Sales Asia Dancs Bela Operations Europe Schwartz Sylvie Operations Europe 已选择25行。 SQL>
笛卡尔积
SELECT id , first_name , last_name , manager_id FROM s_emp ;
创建一个无限极分类表( 某个分类下可以有子分类,子分类可以继续有子分类)
CREATE TABLE t_categories (
id NUMBER(10) ,
name VARCHAR2(20) ,
pid NUMBER(10) ,
CONSTRAINT t_categories_id_pk PRIMARY KEY ( id ) ,
CONSTRAINT t_categories_pid_fk FOREIGN KEY ( pid ) REFERENCES t_categories ( id )
)
查看索引
SELECT index_name , index_type FROM user_indexes WHERE lower(table_name) = 't_categories' ;
查看约束
SELECT constraint_name , constraint_type FROM user_constraints WHERE lower(table_name) = 't_categories' ;
向 t_categories 表中批量插入数据
INSERT ALL
INTO t_categories ( id , name ) VALUES ( 1, '家用电器')
INTO t_categories ( id , name , pid ) VALUES ( 2 , '手机/运营商/数码' , null )
INTO t_categories ( id , name , pid ) VALUES ( 3 , '电视' , 1 )
INTO t_categories ( id , name , pid ) VALUES ( 4 , '空调' , 1 )
SELECT * FROM dual ;
commit ;
连接查询 的一个特殊应用: 自连接
1、自连接(内连接):查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名
SELECT e.empno , e.ename , m.empno , m.ename
FROM emp e INNER JOIN emp m
ON e.mgr = m.empno ;
-- emp表是张自关联的表,我们先将emp表当员工表对待,取别名e;
-- 再将emp表当上司表对待,取别名m,用内连接查询数据
SELECT e.empno 员工工号 , e.ename 员工姓名 , m.empno 上司工号, m.ename 上司姓名
FROM emp eINNER JOIN emp m
ON e.mgr = m.empno ;
2、左外连接:查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名,如果某个雇员没有上司,也将其显示在查询结果中
SELECT e.empno , e.ename , m.empno , m.ename
FROM emp e LEFT OUTER JOIN emp m
ON e.mgr = m.empno ;
3、右外连接:查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名,如果某个上司没有雇员,也将其显示在查询结果中
SELECT e.empno 员工工号, e.ename 员工姓名, m.empno 上司工号, m.ename 上司姓名
FROM emp e RIGHT OUTER JOIN emp m
ON e.mgr = m.empno ;
4、全外连接:查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名;如果 某个员工 没有上司也将其列到查询结果中; 如果 某个员工 不是其他任何员工上司(也就是不是领导)也将其列到查询结果中
SELECT e.empno 员工工号 , e.ename 员工姓名 , m.empno 上司工号, m.ename 上司姓名
FROM emp e FULL OUTER JOIN emp m
ON e.mgr = m.empno ;
SQL> -- 查看 emp 表的表结构 SQL> SQL> DESC emp; 名称 是否为空? 类型 ----------------------------------------------------------------- -------- -------------------------------------------- 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> START format.sql SQL> -- 查看 emp 表中的所有数据 SQL> SELECT * FROM emp ; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-12月-80 800 20 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7788 SCOTT ANALYST 7566 09-12月-82 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7876 ADAMS CLERK 7788 12-1月 -83 1100 20 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ---------- ---------- ---------- 7900 JAMES CLERK 7698 03-12月-81 950 30 7902 FORD ANALYST 7566 03-12月-81 3000 20 7934 MILLER CLERK 7782 23-1月 -82 1300 10 9257 HUA'AN CLERK 7839 23-1月 -85 1300 8526 QIU'XIANG ANALYST 7839 23-1月 -85 1400 已选择16行。 SQL> SQL> -- 查看 s_emp 表的表结构 SQL> DESC s_emp ; 名称 是否为空? 类型 ----------------------------------------------------------------- -------- -------------------------------------------- ID NOT NULL NUMBER(7) LAST_NAME NOT NULL VARCHAR2(25) FIRST_NAME VARCHAR2(25) USERID VARCHAR2(8) START_DATE DATE COMMENTS VARCHAR2(255) MANAGER_ID NUMBER(7) TITLE VARCHAR2(25) DEPT_ID NUMBER(7) SALARY NUMBER(11,2) COMMISSION_PCT NUMBER(4,2) SQL> START format.sql SQL> SELECT * FROM s_emp ; ID LAST_NAME FIRST_NAME USERID START_DATE COMMENTS MANAGER_ID TITLE DEPT_ID SALARY COMMISSION_PCT --- --------------- --------------- -------- -------------- ---------- ---------- --------------- ------- ---------- -------------- 01 Velasquez Carmen cvelasqu 03-3月 -90 President 50 2500 02 Ngao LaDoris lngao 08-3月 -90 01 VP, Operations 41 1450 03 Nagayama Midori mnagayam 17-6月 -91 01 VP, Sales 31 1400 04 Quick-To-See Mark mquickto 07-4月 -90 01 VP, Finance 10 1450 05 Ropeburn Audry aropebur 04-3月 -90 01 VP, Administrat 50 1550 ion 06 Urguhart Molly murguhar 18-6月 -91 02 Warehouse Manag 41 1200 er 07 Menchu Roberta rmenchu 14-5月 -90 02 Warehouse Manag 42 1250 er 08 Biri Ben bbiri 07-4月 -90 02 Warehouse Manag 43 1100 er 09 Catchpole Antoinette acatchpo 09-2月 -92 02 Warehouse Manag 44 1300 er 10 Havel Marta mhavel 27-2月 -91 02 Warehouse Manag 45 1307 er ID LAST_NAME FIRST_NAME USERID START_DATE COMMENTS MANAGER_ID TITLE DEPT_ID SALARY COMMISSION_PCT --- --------------- --------------- -------- -------------- ---------- ---------- --------------- ------- ---------- -------------- 11 Magee Colin cmagee 14-5月 -90 03 Sales Represent 31 1400 10 ative 12 Giljum Henry hgiljum 18-1月 -92 03 Sales Represent 32 1490 12.5 ative 13 Sedeghi Yasmin ysedeghi 18-2月 -91 03 Sales Represent 33 1515 10 ative 14 Nguyen Mai mnguyen 22-1月 -92 03 Sales Represent 34 1525 15 ative 15 Dumas Andre adumas 09-10月-91 03 Sales Represent 35 1450 17.5 ative 16 Maduro Elena emaduro 07-2月 -92 06 Stock Clerk 41 1400 17 Smith George gsmith 08-3月 -90 06 Stock Clerk 41 940 18 Nozaki Akira anozaki 09-2月 -91 07 Stock Clerk 42 1200 19 Patel Vikram vpatel 06-8月 -91 07 Stock Clerk 42 795 20 Newman Chad cnewman 21-7月 -91 08 Stock Clerk 43 750 21 3karian Alexander a3kari 26-5月 -91 08 Stock Clerk 43 850 22 Chang Eddie echang 30-11月-90 09 Stock Clerk 44 800 ID LAST_NAME FIRST_NAME USERID START_DATE COMMENTS MANAGER_ID TITLE DEPT_ID SALARY COMMISSION_PCT --- --------------- --------------- -------- -------------- ---------- ---------- --------------- ------- ---------- -------------- 23 Patel Radha rpatel 17-10月-90 09 Stock Clerk 34 795 24 Dancs Bela bdancs 17-3月 -91 10 Stock Clerk 45 860 25 Schwartz Sylvie sschwart 09-5月 -91 10 Stock Clerk 45 1100 已选择25行。 SQL> SELECT empno , ename , mgr FROM emp ; EMPNO ENAME MGR ---------- ---------- ---------- 7369 SMITH 7902 7499 ALLEN 7698 7521 WARD 7698 7566 JONES 7839 7654 MARTIN 7698 7698 BLAKE 7839 7782 CLARK 7839 7788 SCOTT 7566 7839 KING 7844 TURNER 7698 7876 ADAMS 7788 EMPNO ENAME MGR ---------- ---------- ---------- 7900 JAMES 7698 7902 FORD 7566 7934 MILLER 7782 9257 HUA'AN 7839 8526 QIU'XIANG 7839 已选择16行。 SQL> -- 笛卡尔积 SQL> SELECT id , first_name , last_name , manager_id FROM s_emp ; ID FIRST_NAME LAST_NAME MANAGER_ID --- --------------- --------------- ---------- 01 Carmen Velasquez 02 LaDoris Ngao 01 03 Midori Nagayama 01 04 Mark Quick-To-See 01 05 Audry Ropeburn 01 06 Molly Urguhart 02 07 Roberta Menchu 02 08 Ben Biri 02 09 Antoinette Catchpole 02 10 Marta Havel 02 11 Colin Magee 03 ID FIRST_NAME LAST_NAME MANAGER_ID --- --------------- --------------- ---------- 12 Henry Giljum 03 13 Yasmin Sedeghi 03 14 Mai Nguyen 03 15 Andre Dumas 03 16 Elena Maduro 06 17 George Smith 06 18 Akira Nozaki 07 19 Vikram Patel 07 20 Chad Newman 08 21 Alexander 3karian 08 22 Eddie Chang 09 ID FIRST_NAME LAST_NAME MANAGER_ID --- --------------- --------------- ---------- 23 Radha Patel 09 24 Bela Dancs 10 25 Sylvie Schwartz 10 已选择25行。 SQL> SQL> SQL> -- 创建一个无限极分类表( 某个分类下可以有子分类,子分类可以继续有子分类) SQL> CREATE TABLE t_categories ( 2 SQL> DESC t_categories ; ERROR: ORA-04043: 对象 t_categories 不存在 SQL> CREATE TABLE t_categories ( 2 id NUMBER(10) , 3 name VARCHAR2(20) , 4 pid NUMBER(10) , 5 PRIM 6 ; * 第 6 行出现错误: ORA-00907: 缺失右括号 SQL> ed 已写入 file afiedt.buf 1 CREATE TABLE t_categories ( 2 id NUMBER(10) , 3 name VARCHAR2(20) , 4 pid NUMBER(10) , 5 CONSTRAINT t_categories_id_pk PRIMARY KEY ( id ) , 6 CONSTRAINT t_categories_pid_fk FOREIGN KEY ( pid ) REFERENCES t_categories ( id ) 7* ) SQL> / 表已创建。 SQL> DESC t_categories ; 名称 是否为空? 类型 ----------------------------------------------------------------- -------- -------------------------------------------- ID NOT NULL NUMBER(10) NAME VARCHAR2(20) PID NUMBER(10) SQL> SQL> -- 查看索引 SQL> SELECT index_name , index_type FROM user_indexes WHERE lower(table_name) = 't_categories' ; INDEX_NAME INDEX_TYPE ------------------------------ --------------------------- T_CATEGORIES_ID_PK NORMAL SQL> SQL> -- 查看约束 SQL> SELECT constraint_name , constraint_type FROM user_constraints WHERE lower(table_name) = 't_categories' ; CONSTRAINT_NAME C ------------------------------ - T_CATEGORIES_PID_FK R T_CATEGORIES_ID_PK P SQL> SQL> SQL> -- 向 t_categories 表中插入数据 SQL> SQL> INSERT ALL 2 INTO t_categories ( id , name ) VALUES ( 1 , '家用电器' ) 3 INTO t_categories ( id , name , pid ) VALUES ( 2 , '手机/运营商/数码' , null ) 4 INTO t_categories ( id , name , pid ) VALUES ( 3 , '电视' , 1 ) 5 INTO t_categories ( id , name , pid ) VALUES ( 4 , '空调' , 1 ) 6 SELECT * FROM dual ; 已创建4行。 SQL> commit ; 提交完成。 SQL> SELECT * FROM t_categories ; ID NAME PID --- -------------------- ---------- 01 家用电器 02 手机/运营商/数码 03 电视 1 04 空调 1 SQL> SQL> SQL> SQL> SQL> SQL> -- 查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名 SQL> SQL> SELECT e.empno , e.ename , m.empno , m.ename 2 FROM emp e 3 INNER JOIN emp m 4 ON e.mgr = m.empno ; EMPNO ENAME EMPNO ENAME ---------- ---------- ---------- ---------- 7902 FORD 7566 JONES 7788 SCOTT 7566 JONES 7900 JAMES 7698 BLAKE 7844 TURNER 7698 BLAKE 7654 MARTIN 7698 BLAKE 7521 WARD 7698 BLAKE 7499 ALLEN 7698 BLAKE 7934 MILLER 7782 CLARK 7876 ADAMS 7788 SCOTT 8526 QIU'XIANG 7839 KING 9257 HUA'AN 7839 KING EMPNO ENAME EMPNO ENAME ---------- ---------- ---------- ---------- 7782 CLARK 7839 KING 7698 BLAKE 7839 KING 7566 JONES 7839 KING 7369 SMITH 7902 FORD 已选择15行。 SQL> -- 自连接 SQL> -- emp表是张自关联的表,我们先将emp表当员工表对待,取别名e;再将emp表当上司表对待,取别名m,用内连接查询数据 SQL> set pagesize 25 SQL> SELECT e.empno 员工工号 , e.ename 员工姓名 , m.empno 上司工号, m.ename 上司姓名 2 FROM emp e 3 INNER JOIN emp m 4 ON e.mgr = m.empno ; 员工工号 员工姓名 上司工号 上司姓名 ---------- ---------- ---------- ---------- 7902 FORD 7566 JONES 7788 SCOTT 7566 JONES 7900 JAMES 7698 BLAKE 7844 TURNER 7698 BLAKE 7654 MARTIN 7698 BLAKE 7521 WARD 7698 BLAKE 7499 ALLEN 7698 BLAKE 7934 MILLER 7782 CLARK 7876 ADAMS 7788 SCOTT 8526 QIU'XIANG 7839 KING 9257 HUA'AN 7839 KING 7782 CLARK 7839 KING 7698 BLAKE 7839 KING 7566 JONES 7839 KING 7369 SMITH 7902 FORD 已选择15行。 SQL> -- 以上查询结果中不包含 King ,因为它没有直接上司 SQL> SQL> SQL> -- 查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名 SQL> -- 如果某个雇员没有上司,也将其显示在查询结果中 SQL> SQL> -- 左外连接 SQL> SELECT e.empno 员工工号 , e.ename 员工姓名 , m.empno 上司工号, m.ename 上司姓名 2 FROM emp e LEFT OUTER JOIN emp m ON e.mgr = m.empno ; 员工工号 员工姓名 上司工号 上司姓名 ---------- ---------- ---------- ---------- 7902 FORD 7566 JONES 7788 SCOTT 7566 JONES 7900 JAMES 7698 BLAKE 7844 TURNER 7698 BLAKE 7654 MARTIN 7698 BLAKE 7521 WARD 7698 BLAKE 7499 ALLEN 7698 BLAKE 7934 MILLER 7782 CLARK 7876 ADAMS 7788 SCOTT 8526 QIU'XIANG 7839 KING 9257 HUA'AN 7839 KING 7782 CLARK 7839 KING 7698 BLAKE 7839 KING 7566 JONES 7839 KING 7369 SMITH 7902 FORD 7839 KING 已选择16行。 SQL> -- 右外连接 SQL> SELECT e.empno 员工工号 , e.ename 员工姓名 , m.empno 上司工号, m.ename 上司姓名 2 FROM emp m RIGHT OUTER JOIN emp e ON e.mgr = m.empno ; 员工工号 员工姓名 上司工号 上司姓名 ---------- ---------- ---------- ---------- 7902 FORD 7566 JONES 7788 SCOTT 7566 JONES 7900 JAMES 7698 BLAKE 7844 TURNER 7698 BLAKE 7654 MARTIN 7698 BLAKE 7521 WARD 7698 BLAKE 7499 ALLEN 7698 BLAKE 7934 MILLER 7782 CLARK 7876 ADAMS 7788 SCOTT 8526 QIU'XIANG 7839 KING 9257 HUA'AN 7839 KING 7782 CLARK 7839 KING 7698 BLAKE 7839 KING 7566 JONES 7839 KING 7369 SMITH 7902 FORD 7839 KING 已选择16行。 SQL> SQL> SQL> SQL> -- 有同学会尝试全外连接 SQL> SELECT e.empno 员工工号 , e.ename 员工姓名 , m.empno 上司工号, m.ename 上司姓名 2 FROM emp e FULL OUTER JOIN emp m ON e.mgr = m.empno ; 员工工号 员工姓名 上司工号 上司姓名 ---------- ---------- ---------- ---------- 7369 SMITH 7499 ALLEN 7521 WARD 7902 FORD 7566 JONES 7788 SCOTT 7566 JONES 7654 MARTIN 7900 JAMES 7698 BLAKE 7844 TURNER 7698 BLAKE 7654 MARTIN 7698 BLAKE 7521 WARD 7698 BLAKE 7499 ALLEN 7698 BLAKE 7934 MILLER 7782 CLARK 7876 ADAMS 7788 SCOTT 8526 QIU'XIANG 7839 KING 9257 HUA'AN 7839 KING 7782 CLARK 7839 KING 7698 BLAKE 7839 KING 7566 JONES 7839 KING 7844 TURNER 7876 ADAMS 7900 JAMES 7369 SMITH 7902 FORD 员工工号 员工姓名 上司工号 上司姓名 ---------- ---------- ---------- ---------- 7934 MILLER 9257 HUA'AN 8526 QIU'XIANG 7839 KING 已选择26行。 SQL> -- 以上查询的含义是: SQL> -- 查询 emp 表中 所有雇员的 工号、姓名 及其直接上司的 工号、姓名 SQL> -- 如果 某个员工 没有上司也将其列到查询结果中 SQL> -- 如果 某个员工 不是其他任何员工上司(也就是不是领导)也将其列到查询结果中 SQL> SQL> -- 以上就是 连接查询 的一个特殊应用: 自连接 SQL> SQL> spool off
MySQL也支持这种非标准写法
查询 emp 表中 所有雇员的工号、姓名、部门号、部门名称
建议通过 执行计划 来对比以下两个SQL的执行过程
-- 内连接(SQL标准写法)
SELECT e.empno , e.ename , d.deptno , d.dname
FROM emp e JOIN dept d
ON e.deptno = d.deptno ;
-- 内连接(非SQL标准写法)
SELECT e.empno , e.ename , d.deptno , d.dname
FROM emp e , dept d
WHERE e.deptno = d.deptno ;
查询 emp 表中 所有雇员的工号、姓名、部门号、部门名称,将没有部门的雇员信息也统计在查询结果中
-- 左外连接( SQL标准写法 )
SELECT e.empno , e.ename , d.deptno , d.dname
FROM emp e LEFT JOIN dept d
ON e.deptno = d.deptno ;
-- 左外连接( 非SQL标准写法 )
-- d.deptno(+)的(+)说明,当e.deptno(逗号左侧)包含不满足连接条件的数据时,在部门表d的dept列处加空行
-- 非标准写法里的 左、右 按【逗号】区分,虽然where后的(+)在哪也可区分左右,但=靠不住,因为=的两边是可调换的
SELECT e.empno , e.ename , d.deptno , d.dname
FROM emp e , dept d
WHERE e.deptno = d.deptno(+) ;
查询 emp 表中 所有雇员的工号、姓名、部门号、部门名称,将没有雇员的部门信息也统计在查询结果中
-- 右外连接( SQL标准写法 )
SELECT e.empno , e.ename , d.deptno , d.dname
FROM dept d RIGHT JOIN emp e
ON e.deptno = d.deptno ;
-- 右外连接( 非SQL标准写法 )
-- d.deptno(+)的(+)说明,当e.deptno(逗号右侧)包含不满足连接条件的数据时,在部门表d的dept列处加空行
-- 写法一:
SELECT e.empno , e.ename , d.deptno , d.dname
FROM dept d , emp e
WHERE e.deptno = d.deptno(+);
-- 写法二:
SELECT e.empno , e.ename , d.deptno , d.dname
FROM dept d , emp e
WHERE d.deptno(+) = e.deptno ;
所以就有了以下写法(可能、也许、大概),这是错误的!!
SELECT e.empno , e.ename , d.deptno , d.dname
FROM dept d , emp e
WHERE d.deptno(+) = e.deptno(+) ;
记住,不能在 WHERE 子句的 = 前后同时使用 (+)
因为,一个谓词只能引用一个外部联接的表
什么是 “谓词” ? ? ?
SQL> SQL> -- 关于连接查询的非标准写法 SQL> SQL> -- 查询 emp 表中 所有雇员的工号、姓名、部门号、部门名称 SQL> SQL> -- 内连接( SQL标准写法 ) SQL> SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM emp e JOIN dept d ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7369 SMITH 20 RESEARCH 7499 ALLEN 30 SALES 7521 WARD 30 SALES 7566 JONES 20 RESEARCH 7654 MARTIN 30 SALES 7698 BLAKE 30 SALES 7782 CLARK 10 ACCOUNTING 7788 SCOTT 20 RESEARCH 7839 KING 10 ACCOUNTING 7844 TURNER 30 SALES 7876 ADAMS 20 RESEARCH 7900 JAMES 30 SALES 7902 FORD 20 RESEARCH 7934 MILLER 10 ACCOUNTING 已选择14行。 SQL> SQL> -- 内连接( 非SQL标准写法) SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM emp e , dept d 3 WHERE e.deptno = d.deptno ; EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7369 SMITH 20 RESEARCH 7499 ALLEN 30 SALES 7521 WARD 30 SALES 7566 JONES 20 RESEARCH 7654 MARTIN 30 SALES 7698 BLAKE 30 SALES 7782 CLARK 10 ACCOUNTING 7788 SCOTT 20 RESEARCH 7839 KING 10 ACCOUNTING 7844 TURNER 30 SALES 7876 ADAMS 20 RESEARCH 7900 JAMES 30 SALES 7902 FORD 20 RESEARCH 7934 MILLER 10 ACCOUNTING 已选择14行。 SQL> SQL> -- 建议通过 执行计划 来对比以上两个SQL的执行过程 SQL> SQL> SQL> SQL> -- 查询 emp 表中 所有雇员的工号、姓名、部门号、部门名称,将没有部门的雇员信息也统计在查询结果中 SQL> SQL> -- 左外连接( SQL标准写法 ) SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM emp e LEFT JOIN dept d ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7934 MILLER 10 ACCOUNTING 7839 KING 10 ACCOUNTING 7782 CLARK 10 ACCOUNTING 7902 FORD 20 RESEARCH 7876 ADAMS 20 RESEARCH 7788 SCOTT 20 RESEARCH 7566 JONES 20 RESEARCH 7369 SMITH 20 RESEARCH 7900 JAMES 30 SALES 7844 TURNER 30 SALES 7698 BLAKE 30 SALES 7654 MARTIN 30 SALES 7521 WARD 30 SALES 7499 ALLEN 30 SALES 8526 QIU'XIANG 9257 HUA'AN 已选择16行。 SQL> -- 左外连接( 非SQL标准写法 ) SQL> -- d.deptno(+)的(+)说明在部门表dept处加空行,当e.deptno包含不满足连接条件的数据时 SQL> -- 非标准写法里的 左、右 按【逗号】区分,虽然where后的(+)在哪也可区分左右,但=靠不住,=的两边可调换 SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM emp e , dept d 3 WHERE e.deptno = d.deptno(+) ; EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7934 MILLER 10 ACCOUNTING 7839 KING 10 ACCOUNTING 7782 CLARK 10 ACCOUNTING 7902 FORD 20 RESEARCH 7876 ADAMS 20 RESEARCH 7788 SCOTT 20 RESEARCH 7566 JONES 20 RESEARCH 7369 SMITH 20 RESEARCH 7900 JAMES 30 SALES 7844 TURNER 30 SALES 7698 BLAKE 30 SALES 7654 MARTIN 30 SALES 7521 WARD 30 SALES 7499 ALLEN 30 SALES 8526 QIU'XIANG 9257 HUA'AN 已选择16行。 SQL> SQL> -- 右外连接( SQL标准写法 ) SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM dept d RIGHT JOIN emp e ON e.deptno = d.deptno ; EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7934 MILLER 10 ACCOUNTING 7839 KING 10 ACCOUNTING 7782 CLARK 10 ACCOUNTING 7902 FORD 20 RESEARCH 7876 ADAMS 20 RESEARCH 7788 SCOTT 20 RESEARCH 7566 JONES 20 RESEARCH 7369 SMITH 20 RESEARCH 7900 JAMES 30 SALES 7844 TURNER 30 SALES 7698 BLAKE 30 SALES 7654 MARTIN 30 SALES 7521 WARD 30 SALES 7499 ALLEN 30 SALES 8526 QIU'XIANG 9257 HUA'AN 已选择16行。 SQL> -- 右外连接( 非SQL标准写法 ) SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM dept d , emp e 3 WHERE e.deptno = d.deptno(+); EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7934 MILLER 10 ACCOUNTING 7839 KING 10 ACCOUNTING 7782 CLARK 10 ACCOUNTING 7902 FORD 20 RESEARCH 7876 ADAMS 20 RESEARCH 7788 SCOTT 20 RESEARCH 7566 JONES 20 RESEARCH 7369 SMITH 20 RESEARCH 7900 JAMES 30 SALES 7844 TURNER 30 SALES 7698 BLAKE 30 SALES 7654 MARTIN 30 SALES 7521 WARD 30 SALES 7499 ALLEN 30 SALES 8526 QIU'XIANG 9257 HUA'AN 已选择16行。 SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM dept d , emp e 3 WHERE d.deptno(+) = e.deptno ; EMPNO ENAME DEPTNO DNAME ---------- ---------- ---------- -------------- 7934 MILLER 10 ACCOUNTING 7839 KING 10 ACCOUNTING 7782 CLARK 10 ACCOUNTING 7902 FORD 20 RESEARCH 7876 ADAMS 20 RESEARCH 7788 SCOTT 20 RESEARCH 7566 JONES 20 RESEARCH 7369 SMITH 20 RESEARCH 7900 JAMES 30 SALES 7844 TURNER 30 SALES 7698 BLAKE 30 SALES 7654 MARTIN 30 SALES 7521 WARD 30 SALES 7499 ALLEN 30 SALES 8526 QIU'XIANG 9257 HUA'AN 已选择16行。 SQL> SQL> SQL> -- 所以就有了以下写法(可能、也许、大概) SQL> SELECT e.empno , e.ename , d.deptno , d.dname 2 FROM dept d , emp e 3 WHERE d.deptno(+) = e.deptno(+) ; WHERE d.deptno(+) = e.deptno(+) * 第 3 行出现错误: ORA-01468: 一个谓词只能引用一个外部联接的表 SQL> -- 记住,不能在 WHERE 子句的 = 前后同时使用 (+) SQL> -- 为啥子不可以嘞: SQL> -- 一个谓词只能引用一个外部联接的表 SQL> SQL> -- 有一个任务等着你: 什么是 "谓词" ? ? ? SQL> SQL> spool off
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。