oracle之复杂查询之一:多表连接技术
复杂查询之一:多表连接技术
7.1 简单查询的解析方法:
全表扫描:指针从第一条记录开始,依次逐行处理,直到最后一条记录结束;
横向选择+纵向投影=结果集
7.2 多表连接
交叉连接(笛卡尔积)
非等值连接
等值连接 (内连)
外连接 (内连的扩展,左外,右外,全连接)
自连接
自然连接(内连,隐含连接条件,自动匹配连接字段)
复合连接 (多个结果集进行并、交、差)
范例:
create table a (id int, name char(10));
create table b (id int, loc char(10));
insert into a values (1,'a');
insert into a values (2,'b');
insert into a values (2,'c');
insert into a values (4,'d');
insert into b values (1,'A');
insert into b values (2,'B');
insert into b values (3,'C');
commit;
SQL> select * from a;
ID NAME
---------- ----------
1 a
2 b
2 c
4 d
SQL> select * from b;
ID LOC
---------- ----------
1 A
2 B
3 C
7.2.1 交叉连接(笛卡尔积)
连接条件无效或被省略,两个表的所有行都发生连接,所有行的组合都会返回(n*m)
SQL99写法:
SQL> select * from a cross join b;
oracle写法:
SQL> select * from a,b;
ID NAME ID LOC
---------- ---------- ---------- ----------
1 a 1 A
2 b 1 A
2 c 1 A
4 d 1 A
1 a 2 B
2 b 2 B
2 c 2 B
4 d 2 B
1 a 3 C
2 b 3 C
2 c 3 C
4 d 3 C
已选择12行。
非等值连接:(连接条件非等值,也属于内连范畴)
SQL99写法:
SQL> select empno,ename,sal,grade,losal,hisal from emp join salgrade on sal between losal and hisal;
oracle写法:
SQL> select empno,ename,sal,grade,losal,hisal from emp,salgrade where sal between losal and hisal;
EMPNO ENAME SAL GRADE LOSAL HISAL
---------- ---------- ---------- ---------- ---------- ----------
7369 SMITH 800 1 700 1200
7900 JAMES 950 1 700 1200
7876 ADAMS 1100 1 700 1200
7521 WARD 1250 2 1201 1400
7654 MARTIN 1250 2 1201 1400
7934 MILLER 1300 2 1201 1400
7844 TURNER 1500 3 1401 2000
7499 ALLEN 1600 3 1401 2000
7782 CLARK 2450 4 2001 3000
7698 BLAKE 2850 4 2001 3000
7566 JONES 2975 4 2001 3000
7788 SCOTT 3000 4 2001 3000
7902 FORD 3000 4 2001 3000
7839 KING 5000 5 3001 9999
7.2.2 等值连接,典型的内连接
SQL99写法:
SQL> select * from a inner join b on a.id=b.id;
oracle写法:
SQL> select * from a,b where a.id=b.id;
ID NAME ID LOC
---------- ---------- ---------- ----------
1 a 1 A
2 b 2 B
2 c 2 B
7.2.3 外连接包括左外连接,右外连接,全外连接
1)左外连接
SQL99语法:
SQL> select * from a left join b on a.id=b.id;
oracle语法:
SQL> select * from a,b where a.id=b.id(+);
结果:
ID NAME ID LOC
---------- ---------- ---------- ----------
1 a 1 A
2 c 2 B
2 b 2 B
4 d
2)右外连接
SQL99语法:
SQL>select * from a right join b on a.id=b.id;
oracle语法:
SQL> select * from a,b where a.id(+)=b.id;
结果
ID NAME ID LOC
---------- ---------- ---------- ----------
1 a 1 A
2 b 2 B
2 c 2 B
3 C
3)全外连接
SQL99语法:
SQL> select * from a full join b on a.id=b.id;
ID NAME ID LOC
---------- ---------- ---------- ----------
1 a 1 A
2 b 2 B
2 c 2 B
4 d
3 C
oracle语法:
SQL> select * from a,b where a.id=b.id(+)
union
select * from a,b where a.id(+)=b.id;
ID NAME ID LOC
---------- ---------- ---------- ----------
1 a 1 A
2 b 2 B
2 c 2 B
4 d
3 C
7.2.4 自连接
sql99语法:
SQL> select * from a a1 cross join a a2;
oracle语法:
SQL> select * from a a1,a a2;
7.2.5 自然连接(属于内连中等值连接)
在oralce中使用natural join,也就是自然连接。
先看自然连接:
SQL> select * from a natural join b;
ID NAME LOC
---------- ---------- ----------
1 a A
2 b B
2 c B
-----将两个表分别再加一个列ABC后,则有两个公共列(ID列和ABC列),添加数据后,再尝试自然连接如何匹配。
SQL> select * from a;
ID NAME ABC
---------- ---------- ----------
1 a s
2 b t
2 c u
4 d v
SQL> select * from b;
ID LOC ABC
---------- ---------- ----------
1 A w
2 B t
3 C r
SQL> select * from a natural join b;
ID ABC NAME LOC
---------- ---------- ---------- ----------
2 t b B
在自然连接中可以使用using关键字:
当使用natraul join关键字时,如果两张表中有多个字段,它们具有相同的名称和数据类型,那么这些字段都将被oracle自作主张的将他们连接起来。但如果名称相同,类型不同,或者当你需要在多个字段同时满足连接条件的情况下,想人为指定某个(些)字段做连接,那么可以使用using 关键字。
在oracle连接(join)中使用using关键字
SQL> select id,a.abc,name,loc from a join b using(id);
ID ABC NAME LOC
---------- ---------- ---------- ----------
1 s a A
2 t b B
2 u c B
using里未必只能有一列
SQL> select id,abc,name,loc from a join b using(id,abc);
ID ABC NAME LOC
---------- ---------- ---------- ----------
2 t b B
总结:
1、使用using关键字时,如果select的结果列表项中包含了using关键字所指明的那个关键字,那么,不要指明该关键字属于哪个表(考点)。
2、using中可以指定多个列名。
3、natural和using关键字是互斥的,也就是说不能同时出现。
在实际工作中看,内连接,左外连接,以及自然连接用的较多,而且两表连接时一般是多对一的情况居多,即a表行多,b表行少, 从连接字段来看,b表为父表,其连接字段做主键, a表为子表,其连接字段为外键。
典型的就是dept表和emp表的关系,两表连接字段是deptno,建有主外键关系。
这与数据库设计要求符合第三范式有关。
7.3 复合查询(使用集合运算符)
Union,对两个结果集进行并集操作,重复行只取一次,同时进行默认规则的排序;
Union All,对两个结果集进行并集操作,包括所有重复行,不进行排序;
Intersect,对两个结果集进行交集操作,重复行只取一次,同时进行默认规则的排序;
Minus,对两个结果集进行差操作,不取重复行,同时进行默认规则的排序。
复合查询操作有 并,交,差 3种运算。
举例:
SQL> create table dept1 as select * from dept where rownum <=1;
SQL> insert into dept1 values (80, 'MARKTING', 'BEIJING');
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> select * from dept1;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
80 MARKTING BEIJING
7.3.1 union
SQL>
select * from dept
union
select * from dept1;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
80 MARKTING BEIJING
7.3.2 union all
SQL>
select * from dept
union all
select * from dept1;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
10 ACCOUNTING NEW YORK
80 MARKTING BEIJING
特别注意:可以看出只有union all的结果集是不排序的。
7.3.3 intersect
SQL>
select * from dept
intersect
select * from dept1;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
7.3.4 minus (注意谁minus谁)
SQL>
select * from dept
minus
select * from dept1;
DEPTNO DNAME LOC
---------- -------------- -------------
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
select * from dept1
minus
select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
80 MARKTING BEIJING
7.4 复合查询中的几点注意事项
1)列名不必相同,但要类型匹配且顺序要对应,大类型对上就行了,比如char对varchar2,date对timestamp都可以,字段数要等同,不等需要补全。
create table a (id_a int,name_a char(10));
create table b (id_b int,name_b char(10),sal number(10,2));
insert into a values (1, 'sohu');
insert into a values (2, 'sina');
insert into b values (1, 'sohu', 1000);
insert into b values (2, 'yahoo', 2000);
commit;
SQL> select * from a;
ID_A NAME_A
---------- ----------
1 sohu
2 sina
SQL> select * from b;
ID_B NAME_B SAL
---------- ---------- ----------
1 sohu 1000
2 yahoo 2000
SQL>
select id_a,name_a from a
union
select id_b,name_b from b;
ID_A NAME_A
---------- ----------
1 sohu
2 sina
2 yahoo
2)四种集合运算符优先级按自然先后顺序,如有特殊要求可以使用()。
3)关于复合查询中order by 使用别名排序的问题:
a) 缺省情况下,复合查询后的结果集是按所有字段的组合进行排序的(除union all 外)
如果不希望缺省的排序,也可以使用order by显示排序
select id_a, name_a name from a
union
select id_b, name_b name from b
order by name;
ID_A NAME
---------- ----------
2 sina
1 sohu
2 yahoo
select id_a, name_a from a
union
select id_b, name_b from b
order by 2;
ID_A NAME_A
---------- ----------
2 sina
1 sohu
2 yahoo
b) 显式order by是参照第一个select语句的列元素。所以,order by后的列名只能是第一个select使用的列名、别名、列号(考点)。
如果是补全的null值需要order by,则需要使用别名。
SQL>
select id_a, name_a name,to_number(null) from a
union
select id_b, name_b name,sal from b
order by sal;
ORA-00904: "SAL": 标识符无效
SQL>
select id_a, name_a name,to_number(null) from a
union
select id_b, name_b name,sal from b
order by 3;
ID_A NAME TO_NUMBER(NULL)
---------- ---------- ---------------
1 sohu 1000
2 yahoo 2000
1 sohu
2 sina
SQL>
select id_b, name_b name,sal from b
union
select id_a, name_a name,to_number(null) from a
order by sal;
ID_B NAME SAL
---------- ---------- ----------
1 sohu 1000
2 yahoo 2000
1 sohu
2 sina
SQL>
select id_a, name_a name,to_number(null) aa from a
union
select id_b, name_b name,sal aa from b
order by aa;
ID_A NAME AA
---------- ---------- ----------
1 sohu 1000
2 yahoo 2000
1 sohu
2 sina
c) 排序是对复合查询结果集的排序,不能分别对个别表排序,order by 只能一次且出现在最后一行;
SQL>
select id_a, name_a from a order by id_a
union
select id_b, name_b from b order by id_b;
ORA-00933: SQL 命令未正确结束
oracle之复杂查询之一:多表连接技术的更多相关文章
- Oracle使用游标查询所有数据表备注
功能作用:应用对应的SQL语句,能方便快速的查询Oracle数据库指定用户的所有用户表说明,快速知道每个数据表是做什么的,方便写文档和方案. 运行环境:搭建好Oracle数据库,并使用PQ/SQL D ...
- 010.简单查询、分组统计查询、多表连接查询(sql实例)
-------------------------------------day3------------ --添加多行数据:------INSERT [INTO] 表名 [(列的列表)] --SEL ...
- Oracle使用游标查询指定数据表的所有字段名称组合而成的字符串
应用场合:参考网上查询数据表的所有字段名代码,使用游标生成指定单个表的所有字段名跟逗号组成的用于select 逗号隔开的字段名列表 from字符串等场合. 查询结果输出如下: 当前数据表TB_UD_ ...
- Oracle和MSSQL查询有多少张表
Oracle: SELECT count(*) FROM user_tables MSSQL: ) FROM sysobjects WHERE xtype='U' 这种方法可能会把dbo.dtprop ...
- Oracle之分组函数嵌套以及表连接
--1 数据环境准备 scott 用户下面的emp,dept表 --2 要求 :求平均工资最高的部门编号,部门名称,部门平均工资 select d.deptno,d.dname,e.salfrom(s ...
- Oracle 执行计划(三)-------表连接方式
SQL FOR TESTING: create table qcb_student_test( student_id number, student_name varchar2(20), studen ...
- MySQL开发——【联合查询、多表连接、子查询】
联合查询 所谓的联合查询就是将满足条件的结果进行拼接在同一张表中. 基本语法: select */字段 from 数据表1 union [all | distinct] select */字段 fro ...
- 5月10日 python学习总结 单表查询 和 多表连接查询
一. 单表查询 一 语法 select distinct 查询字段1,查询字段2,... from 表名 where 分组之前的过滤条件 group by 分组依据 having 分组之后的过滤条件 ...
- 一条sql,有分页,表合并查询,多表连接,用于oracle数据库
SELECT * FROM ( SELECT TT.*,ROWNUM RN FROM ( SELECT A.CASE_ID AS TREATID, A.TYPE AS TYPE, B.CONTENT ...
随机推荐
- 从0写一个Golang日志处理包
WHY 日志概述 日志几乎是每个实际的软件项目从开发到最后实际运行过程中都必不可少的东西.它对于查看代码运行流程,记录发生的事情等方面都是很重要的. 一个好的日志系统应当能准确地记录需要记录的信息,同 ...
- IOS 崩溃原因统计 2014-07-12 10:13
注意: 1,释放自己的autorelease对象,app会crash: 2,释放系统的autorelease对象,app会crash: 第一种 情况有现象如下: 声明一个 对象 A* obj:把o ...
- Url跳转漏洞常见
Url跳转漏洞常见出现点: 1.用户登录.统一身份认证处,认证完后会跳转. 2.用户分享.收藏内容过后,会跳转. 3.跨站点认证.授权后,会跳转. 4.站内点击其它网址链接时,会跳转. Url跳转漏洞 ...
- Swing记事本项目
具备记事本功能:文件保存.文件打开.复制.黏贴.撤销.全选.字体修改.字体颜色修改.背景颜色修改
- 尾递归(java)
一般递归: 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多 ...
- 蓝牙bluez命令
记录一下自己平时调试蓝牙的命令,后续学习到再添加 sdptool命令: sdptool add SP - 添加SPP: sdptool add --channel=1 DID SP DUN LA ...
- springboot~通过面向接口编程对控制反转IOC的理解
IOC,把控制反转到业务端,这句话没什么问题,在springboot框架里,对象的管理是通过spring ioc来实现的,而开发人员的开发原则里总是说"面向接口编程",而为什么要面 ...
- 操作系统-I/O(6)I/O与系统调用
所有高级语言的运行时(runtime)都提供了执行I/O功能的机制. 例如,C语言中提供了包含像printf()和scanf()等这样的标准I/O库函数, C++语言中提供了如 <<和&g ...
- ACM study day3
今天练了二分和快速幂,题目挺难的,挑几个我做上的说一下吧. 先给出几个二分和快速幂的模板函数: 二分 void BS(int m) { int x=,y=a[m-]-a[]; while(y-x> ...
- vue的修饰符
v-on 缩写:@ 事件修饰符 .stop - 调用 event.stopPropagation(). //阻止冒泡 .prevent - 调用 event.preventDefault(). //阻 ...