- cross join(几乎不用)
- natural join(不指定字段的join,几乎不用)
- inner join
- left join
- right join
JOIN的全程就是INNER JOIN,所以默认就是内连接
取两个表的交集,所以不会有NULL值出现
!> 多表查询时,指明字段的表名能提高查询速度
SELECT emp.ename,
emp.deptno,
dept.dname,
dept.loc
FROM emp,
dept;
emp表有14个记录,dept表有4个记录
查询结果是14*4个记录
SELECT emp.ename,
emp.deptno,
dept.dname,
dept.loc
FROM emp,
dept
WHERE emp.deptno = dept.deptno;
此时只在【显示上】消除了笛卡尔积,
因为数据库的操作机制属于逐行进行数据的判断
如果数据量很大,等值查询性能很差
!> 可用子查询实现多表查询
SELECT e.ename,
-- d.deptno, 不能select两个表相同字段
d.dname,
d.loc
FROM emp e
NATURAL JOIN dept d;
使用USING子句明确指定连接字段
SELECT e.ename,
d.dname,
d.loc
FROM emp e
JOIN dept d
USING (deptno);
SELECT e.ename,
d.dname,
d.loc
FROM emp e
JOIN dept d
ON (e.deptno = d.deptno);
-- ON更灵活些,两个表的字段名可以不同
SELECT e.ename,
e.sal,
s.grade
FROM emp e,
salgrade s
WHERE e.sal BETWEEN s.losal AND s.hisal;
/*
ENAME SAL GRADE
---------- ---------- ----------
SMITH 800 1
原理:比如SMITH的工资时800,去s表查询时,
只有grade1这行满足between...and条件
*/
查询每个雇员的领导名字
每个员工的MGR字段(领导)也是个员工ID
SELECT e.empno,
e.ename,
boss.ename
FROM emp e,
emp boss
WHERE e.mgr = boss.empno;
然而发现结果少了一列,因为主席/总裁上面没有领导
这时就需要左/右连接来解决这个问题
左右指的是查询判断条件的参考方向
(+)放在等号左边就是左连接
SELECT *
FROM emp e,
dept d
WHERE e.deptno = d.deptno;
明明dept表中有40部门,输出结果中却没有
原因是就没有员工在40部门,如果非要显示40部门,就用左/右连接
SELECT *
FROM emp e,
dept d
WHERE e.deptno(+) = d.deptno;
-- 此时多了一个记录,该记录除了deptno为40其余为NULL
!> 不用刻意区分是左是右,如果有些想要的数据没出来,就更改参考方向
-- 查询每个员工的领导名
SELECT e.empno,
e.ename,
boss.ename
FROM emp e,
emp boss
WHERE e.mgr = boss.empno(+);
这个(+)号是Oracle特有的
用笛卡尔积去实现
CREATE TABLE perm (name VARCHAR(8));
INSERT INTO perm VALUES('AA');
INSERT INTO perm VALUES('BB');
INSERT INTO perm VALUES('CC');
INSERT INTO perm VALUES('DD');
COMMIT;
SELECT p1.name,p2.name
FROM perm p1,perm p2
WHERE p1.name!=P2.name;