学习资料

学习的笔记


6多表查询

<h3>多表查询基本语法:</h3> <ul> <li>笛卡尔积,结果的行数是两个表的行数的积,联合查询性能低 <code>SELECT * FROM emp,dept;</code></li> <li>消除笛卡尔积,利用外键的关系来消除,等值连接的方式消除笛卡尔积 <code>SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;</code></li> </ul> <h3>多表查询实例</h3> <pre><code>SELECT a.empno 雇员编号,a.ename 雇员姓名,a.job 职位,a.sal 基本工资,b.dname 部门名称,b.loc 部门位置 FROM emp a,dept b WHERE a.deptno=b.deptno; SELECT * FROM salgrade ;--要求查询员工信息,工资等级,联合查询的条码是很灵活的 SELECT e.empno,e.ename,e.hiredate,e.sal,s.grade,s.losal,s.hisal FROM emp e,salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal; </code></pre> <ul> <li>对工资等级的显示人性化 <pre><code>SELECT e.empno,e.ename,e.hiredate,e.sal,decode(s.grade,'1','E级',2,'D级',3,'C级','4','B级','5','A级') salgrade FROM emp e,salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal </code></pre></li> <li>三表查询,不成文规定:消除笛卡尔积的条码个数=表的张数-1 <pre><code>SELECT e.ename,e.job,e.sal,d.dname,s.grade,decode(s.grade,'1','E级',2,'D级',3,'C级','4','B级','5','A级') grade_1 FROM emp e,dept d,salgrade s WHERE e.deptno = d.deptno AND e.sal BETWEEN s.losal AND s.hisal ;</code></pre></li> </ul> <h3>表的连接操作,两表中没有相等的数据,数据丢失问题</h3> <ul> <li>插入额外的数据 <pre><code>INSERT INTO emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) VALUES (8888,'李兴华','CLERK',7369,SYSDATE,800,100,NULL); SELECT * from emp,dept WHERE emp.deptno = dept.deptno ;</code></pre></li> <li>左连接与右连接用+号实现</li> <li>左连接 <code>SELECT e.empno,e.ename,e.job,d.deptno,d.dname,d.loc FROM emp e,dept d WHERE e.deptno = d.deptno(+);</code></li> <li>右连接 <code>SELECT * FROM emp e,dept d WHERE e.deptno(+) = d.deptno ;</code></li> </ul> <h3>自身关联</h3> <ul> <li>emp表自身关联,查找雇员工号,雇员名字,上司编号,上司名字 <pre><code>SELECT emp.empno,emp.ename,memp.empno,memp.ename FROM emp,emp memp WHERE emp.mgr=memp.empno ; SELECT emp.empno,emp.ename,memp.empno,memp.ename FROM emp,emp memp WHERE emp.mgr=memp.empno(+);</code></pre></li> <li>复杂示例:查询在1981年雇佣的全部雇员编号、姓名、雇用日期(按年-月-日显示)、工作、领导姓名、雇员月工资、雇员年工资(基本工资+奖金),雇员工资等级、部门编号、部门名称、部门位置, --并且要求这些雇员的月基本工资在1500~3500元之间,将最后的结果按照年工资的降序排列,如果年工资相等,则按照工作时间进行排序。 <pre><code>SELECT e.empno,e.ename,to_char(e.hiredate,'yyyy-mm-dd'),e.job,me.ename,e.sal,NVL2(e.comm,e.sal+e.comm,e.sal)*12 yearsal,s.grade,d.deptno,d.dname,d.loc FROM emp e,emp me,salgrade s,dept d WHERE e.mgr=me.empno(+) AND e.deptno=d.deptno(+) AND (e.sal BETWEEN s.losal AND s.hisal) AND (e.sal BETWEEN 1500 AND 3500) AND to_char(e.hiredate,'yyyy')=1981 ORDER BY yearsal DESC,e.hiredate ASC;</code></pre></li> </ul> <h3>SQL:1999语法</h3> <pre><code>SELECT * FROM emp CROSS JOIN dept ;--交叉连接,相当于笛卡尔积 SELECT * FROM emp NATURAL JOIN dept ;--自然连接,有共同字段的记录能连接,不能连接的叫悬浮元组。 SELECT * FROM emp JOIN dept USING(deptno) ;--USING子句指定连接的字段,可以去除重复列 SELECT * FROM emp e JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal) ;--使用on子句指定关系</code></pre> <h3>外连接:左外连接、右外连接、全连接,前面用的(+)号只能是oracle用</h3> <pre><code>SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno ;--左外连接 SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno ;--右外连接 SELECT * FROM emp e FULL OUTER JOIN dept d ON e.deptno=d.deptno ;--全外连接</code></pre> <h3>数据的集合运算,二目运算符:并、差、交、笛卡尔积</h3> <pre><code>/* union(并集):返回查询的结果,去除重复项。 union all(并集):重复项也重复显示。 minus(差集):返回查询结果中不同的部分。 intersect(交集):返回结果中相同的部分。 */</code></pre> <h4>并集操作</h4> <pre><code>SELECT * FROM dept --union重复内容只显示一次 UNION SELECT * FROM dept WHERE deptno=10; --union all重复内容不过滤 SELECT * FROM dept UNION ALL SELECT * FROM dept WHERE deptno=10; --使用or SELECT * FROM emp WHERE job='SALESMAN' OR job='CLERK';--0.031秒 --使用union。使用union、union all能达到or相同的目的,但是使用union、union all的性能更好 SELECT * FROM emp WHERE job='SALESMAN' UNION SELECT * FROM emp WHERE job='CLERK';</code></pre> <h4>差集操作:显示不重叠部分</h4> <pre><code>SELECT * FROM dept MINUS SELECT * FROM dept WHERE deptno=10;</code></pre> <h4>交集操作:只显示重叠部分</h4> <pre><code>SELECT * FROM dept INTERSECT SELECT * FROM dept WHERE deptno=10;</code></pre> <h4>5种连接</h4> <ul> <li>自然连接natural join 不用联接条件、重复的列自动去掉</li> <li>内连接inner join(join) 要联接条件、重复的列不去掉</li> <li>外连接outer join ,分三种left join 、right join 右联接、full join ,即不满足条码的行也可以返回</li> <li>交叉连接cross join ,不带on,只能根据两表的条件减数据,返回笛卡尔积</li> <li>自连接,同一张表多连接</li> </ul> <p><a href="https://www.cnblogs.com/wishyouhappy/p/3678852.html">5种基本类型的连接</a></p> <h3>总结</h3> <ul> <li>数据表连接的方式有:自身连接、外连接、内连接</li> <li>多表连接有oracle特有的连接方法和SQL:1999语法标准两种</li> </ul>

页面列表

ITEM_HTML