数据库的多表查询及左右连接

1、关于多表查询的解决思路

--思考题:要求查询出每个雇员的编号,姓名,工资,部门名称,工资所在公司的工资等级
--第一步确定所需要的表,以及表中字段
  --emp,dept,salgrade
  --emp:雇员编号,姓名,工资
  --dept: 部门名称
  --salgrade: 工资等级

--第二步确定表的关联字段
  --emp.deptno=dept.deptno
  --emp.sal between salgrade.losal and salgrade.hisal

--第三步:查询每个雇员的信息
select e.empno,e.ename,e.sal from emp e

--第四步:为查询引入部门信息,并添加消除笛卡尔积的条件

select e.empno,e.ename,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno

--第五步:为查询引入工资等级信息,并添加消除笛卡尔积德条件

select e.empno,e.ename,e.sal,d.dname,s.grade from emp e,dept d,salgrade s where e.deptno=d.deptno and e.sal between s.losal and s.hisal

2、左右连接

关于左右连接指的是查询判断条件的参考方向,例如:下面有如下查询:

 select * from emp e,dept d where e.deptno = d.deptno; 

部门一共有四个,但是现在只返回了三个部门的信息,缺少40部门,因为在雇员表之中没有一条记录是属于40部门的,所以现在不会显示40部门的信息,即:现在的查询以emp表为参考,那么如果说现在非要显示40部门呢?就必须改变这种参考的方向,就要使用左右连接。

因为SQL1999语法适用于多种数据库所以这里直接学习该语法,一下是属于多个语法的联合

select table1.column,table2.column

from table1 [cross join table2]|

[natural join table2]|

[join table2 using(column_name)]|

[join table2 on(table1.column_name = table2.column_name)]|

[left|right|full outer join table2 on(table1.column_name = table2.column_name];

接下来分块说明语法的使用

a、交叉连接(cross join):用于产生笛卡尔积(笛卡尔积本身并不是属于无用的内容,在某些情况下还是需要使用的)

   select * from emp cross join dept; 

b、自然连接(natural join):自动找到匹配的关联字段,消除掉笛卡尔积

   select * from emp natural join detp 

但是并不是所有的字段都是关联字段,设置关联字段需要通过约束指定;

c、join using子句:用户自己指定一个消除笛卡尔积的关联字段

   select * from emp join dept using(deptno); 

d、join ... on子句:用户自己指定一个可以消除笛卡尔积德关联条件

  select * from emp join dept on(emp.deptno=dept.deptno);  

e、连接方向的改变:

  左(外)连接: left outer join ...on;

  右(外)连接: right outer join ...on;

  全(外)连接: full outer join ...on;

   select * from emp right outer join dept on(emp.deptno=dept.deptno); 

注:在Oracle之外的数据库都是使用的以上的sql:1999语法操作,所以这个语法一定要会。

 

工作中使用的语句

场景1: 两个表查询A and B  其中从 B表中查询出的值做为A表的查询条件进行查询

 SELECT t.name,t.* FROM A t WHERE t.id=(SELECT c.area_id FROM B c  WHERE c.id=193084);

 SELECT c.* FROM A c JOIN B t ON c.id=t.area_id WHERE t.`id`=193084


SELECT * FROM A si LEFT JOIN B st ON si.id = st.f_si 
WHERE si.id IN(85656,85689,85701,85704,85644,85692,85632,85620);

 

posted @ 2015-08-24 23:58  Blue●Sky  阅读(10621)  评论(0编辑  收藏  举报