SQL Fundamentals || Oracle SQL语言

一、多表查询基本语法

  • 在进行多表连接查询的时候,由于数据库内部的处理机制,会产生一些“无用”的数据,而这些数据就称为笛卡尔积.
  • 多表查询时可以利用等值关联字段消除笛卡尔积
  • 多表查询之中,每当增加一个关联表都需要设置消除笛卡尔积的条件
  • 分析过程很重要:
    • 确定所需要的数据表
    • 确定已知的关联字段:
    • 按照SQL语句的执行步骤编写:FROM,WHERE,SELECT,ORDER BY

(由于SELECT是在WHERE子句之后执行,所以SELECT子句所定义的别名WHERE不可以直接使用)

(由于SELECT是在ORDER BY子句之前执行,所以SELECT子句所定义的别名ORDER BY可以直接使用)

二、表的连接操作

  • 内连接、等值连接、连接、普通连接、自然连接
  • 外连接(左外连接,右外连接),外连接可以通过“(+)”符号进行控制。

三、自身关联

自身关联属于一张表自己关联自己的情况,此时依然会产生笛卡尔积

四:SQL:1999语法

交叉连接的:交叉连接会产生笛卡尔积;

自然连接:自然连接可以自动匹配关联字段消除笛卡尔积;

ON子句

USING子句

全外连接:如果要实现全外连接只能够依靠SQL:1999语法。LEFT|RIGHT|FULL OUTER JOIN

五、数据的集合运算

数据的集合操作:UNION、UNION ALL、INTERSECT、MINUS

集合操作时,各个查询语句返回的结构要求一致

开发之中建议使用UNION来代替OR操作

一、多表查询基本语法

1、多表查询的语法:

多表查询就是在一条查询语句中,从多张表里一起取出所需要的数据,如果要想进行多表查询,直接在FROM子句之后跟上多个表即可,此时的语法如下:

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

FROM 表名称1 [表别名1] , 表名称2 [表别名2] ….

[WHERE 条件(s) ]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

2、笛卡尔积:

在进行多表连接查询的时候,由于数据库内部的处理机制,会产生一些“无用”的数据,而这些数据就称为笛卡尔积。

通过之前的查询可以发现,笛卡尔积返回的56条查询结果正好是 14 * 4(emp表数据量 * dept表数据量)的运算结果,即,同一条数据重复显示了N次。

  • 查询emp表中的数据量 —— 14条数据

SELECT COUNT(*) FROM emp ;

  • 查询dept表中的数据量 —— 4条数据

SELECT COUNT(*) FROM dept ;

  • 现在查询所有的雇员和部门的全部详细信息

SELECT * FROM emp,dept ;

3、消除笛卡尔积:

多表查询会产生笛卡尔积,所以性能较差;

多表查询时可以利用等值关联字段消除笛卡尔积。

SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno ;

SELECT * FROM emp e , dept d WHERE e.deptno=d.deptno;

4、举例:查询每个雇员的编号、姓名、职位、基本工资、部门名称、部门位置信息

分析过程:

  • 确定所需要的数据表
    • emp表
    • dept表
  • 确定已知的关联字段:
    • 部门和雇员的关联:emp.deptno=dept.depno
  • 按照SQL语句的执行步骤编写:FROM,WHERE,SELECT

SELECT emp.empno,emp.ename,emp.job,emp.sal,dept.dname,dept.loc

FROM emp,dept

WHERE emp.deptno=dept.deptno ;

5、给表设置别名,查询雇员的编号、姓名、职位、基本工资、部门名称、部门位置

SELECT e.empno,e.ename,e.job,e.sal,d.dname,d.loc

FROM emp e,dept d

WHERE e.deptno=d.deptno ;

6、BETWEEN AND查询出每个雇员的编号、姓名、雇佣日期、基本工资、工资等级

SELECT e.empno,e.ename,e.hiredate,e.sal,s.grade

FROM emp e,salgrade s

WHERE e.sal BETWEEN s.losal AND s.hisal ;

7、DECODE为了更加清楚的显示出工资等级的信息,现在希望可以按如下格式进行替换显示:

  • grade=1:显示为“E等工资”
  • grade=2:显示为“D等工资”
  • grade=3:显示为“C等工资”
  • grade=4:显示为“B等工资”
  • grade=5:显示为“A等工资”

SELECT e.empno,e.ename,e.hiredate,e.sal,

DECODE(s.grade,1,'E等工资',2,'D等工资',3,'C等工资',4,'B等工资',5,'A等工资') grade

FROM emp e,salgrade s

WHERE e.sal BETWEEN s.losal AND s.hisal ;

8、查询出每个雇员的姓名、职位、基本工资、部门名称、工资所在公司的工资等级;

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

FROM emp e,dept d,salgrade s

WHERE e.deptno=d.deptno AND e.sal BETWEEN s.losal AND s.hisal ;

二、表的连接操作

对于数据表的连接操作在数据库之中一共定义了两种:

内连接

等值连接

连接

普通连接

自然连接

是最早的一种连接方式,

内连接是从结果表中删除与其他被连接表中没有匹配行的所有元组,所以当匹配条件不满足时内连接可能会丢失信息。

在之前所使用的连接方式都属于内连接,而在WHERE子句之中设置的消除笛卡尔积的条件就采用了等值判断的方式进行的;

举例:现在将emp和dept表联合查询,使用内连接(等值连接)

SELECT *

FROM emp e,dept d

WHERE e.deptno=d.deptno ;

外连接

内连接中只能够显示等值满足的条件,如果不满足的条件则无法显示,

如果现在希望特定表中的数据可以全部显示,就利用外连接,

外连接分为三种:

左外连接(简称:左连接)

右外连接(简称:右连接)

全外连接(简称:全连接)

在Oracle中可以利用其提供的“(+)”进行左外连接或右外连接的实现,使用如下:

  • 左关系属性=右关系属性(+):“(+)”放在了等号的右边,所以此时表示的是左连接;
  • 左关系属性(+)=右关系属性:“(+)”放在了等号的左边,所以此时表示的是右连接;

使用左外连接,

SELECT *

FROM emp e,dept d

WHERE e.deptno=d.deptno(+) ;

增加右外连接,显示部门40的信息

SELECT *

FROM emp e,dept d

WHERE e.deptno(+)=d.deptno ;

三、自身关联

1、举例:

查询出每个雇员的编号、姓名及其上级领导的编号、姓名,

只需要用到一个emp表中的两个字段,将emp表分别别名为e和m

SQL> SELECT ename,empno,mgr FROM emp;

ENAME           EMPNO        MGR

---------- ---------- ----------

SMITH            7369       7902

FORD             7902       7566

SQL> SELECT e.empno eno, e.ename ename,m.empno mno,m.ename mname

2 FROM emp e,emp m

3 WHERE e.mgr=m.empno;

ENO ENAME             MNO MNAME

7369 SMITH            7902 FORD

SELECT e.empno eno ,e.ename ename,m.empno mno,m.ename mname

FROM emp e,emp m

WHERE e.mgr=m.empno(+) ;

2、举例:

查询出在1981年雇佣的全部雇员的编号、姓名、雇佣日期(按照年-月-日显示)、工作、领导姓名、雇员月工资、雇员年工资(基本工资+奖金),雇员工资等级、部门编号、部门名称、部门位置,并且要求这些雇员的月基本工资在1500~3500之间,将最后的结果按照年工资的降序排列,如果年工资相等,则按照工作进行排序

步骤一:查询emp表中的信息(全部雇员的编号、姓名、雇佣日期(按照年-月-日显示),月基本工资在1500~3500之间)

SELECT e.empno,e.ename,e.hiredate,e.sal,(e.sal+NVL(e.comm,0))*12 income

FROM emp e

WHERE   TO_CHAR(e.hiredate,'yyyy')='1981' AND e.sal BETWEEN 1500 AND 3500

步骤二:emp表使用自身关联,加入领导的信息,使用别名设置emp表的别名为m,使用关联条件e.mgr=m.empno(+) 消除笛卡尔积

SELECT e.empno,e.ename,e.hiredate,e.sal,(e.sal+NVL(e.comm,0))*12 income , m.ename mname

FROM emp e ,em m

WHERE   TO_CHAR(e.hiredate,'yyyy')='1981' AND e.sal BETWEEN 1500 AND 3500

AND e.mgr=m.empno(+)

步骤三:dept表加入部门信息,使用外连接 e.mgr=m.empno(+),使用关联条件 e.deptno=d.deptno 消除笛卡尔积

SELECT e.empno,e.ename,e.hiredate,e.sal,(e.sal+NVL(e.comm,0))*12 income , m.ename mname ,d.deptno,d.dname,d.loc

FROM emp e ,em m , dept d

WHERE   TO_CHAR(e.hiredate,'yyyy')='1981' AND e.sal BETWEEN 1500 AND 3500

AND e.mgr=m.empno(+)

AND e.deptno=d.deptno

步骤四:salgrade表查询工资等级,使用关联条件 e.sal BETWEEN s.losal AND s.hisal 消除笛卡尔积

SELECT e.empno,e.ename,e.hiredate,e.sal,(e.sal+NVL(e.comm,0))*12 income , m.ename mname ,

d.deptno,d.dname,d.loc ,

s.grade, DECODE(s.grade,1,'E等工资',2,'D等工资',3,'C等工资',4,'B等工资',5,'A等工资') 工资等级

FROM emp e , emp m , dept d , salgrade s

WHERE   TO_CHAR(e.hiredate,'yyyy')='1981' AND e.sal BETWEEN 1500 AND 3500

AND e.mgr=m.empno(+)

AND e.deptno=d.deptno

AND e.sal BETWEEN s.losal AND s.hisal

步骤五:进行排序,

由于SELECT是在ORDER BY子句之前执行,所以SELECT子句所定义的别名ORDER BY可以直接使用

SELECT e.empno,e.ename,e.hiredate,e.sal,(e.sal+NVL(e.comm,0))*12 income , m.ename mname ,

d.deptno,d.dname,d.loc ,

s.grade, DECODE(s.grade,1,'E等工资',2,'D等工资',3,'C等工资',4,'B等工资',5,'A等工资') 工资等级

FROM emp e , emp m , dept d , salgrade s

WHERE   TO_CHAR(e.hiredate,'yyyy')='1981' AND e.sal BETWEEN 1500 AND 3500

AND e.mgr=m.empno(+)

AND e.deptno=d.deptno

AND e.sal BETWEEN s.losal AND s.hisal

ORDER BY income DESC , e.job ;

四:SQL:1999语法

SQL:1999语法

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

FROM 表1 表别名1 [CROSS JOIN 表2 表别名2]|

[NATURAL JOIN 表2 表别名2]|

[JOIN 表2 USING(关联列名称)]|

[JOIN 表2 ON(关联条件)]|

[LEFT|RIGHT|FULL OUTER JOIN 表2 ON(关联条件)]

[WHERE 条件(s)]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

交叉连接(CROSS JOIN)

作用于两个关系上,并且第一个关系的每个元组与第二个关系的所有元组进行连接,这样的操作形式与笛卡尔积是完全相同的,

交叉连接的语法:

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

]|

[WHERE 条件(s)]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

使用交叉连接(CROSS JOIN),产生笛卡尔积

SELECT * FROM emp CROSS JOIN dept ;

使用自然连接(NATION JOIN)

自然连接(NATURAL JOIN)运算作用于两个关系,最终会通过两个关系产生出一个关系作为结果。

与交叉连接(笛卡尔积)不同的是, 自然连接只考虑那些在两个关系模式中都出现的属性上取值相同的元组对。

自然连接的操作语法:

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

[NATURAL JOIN 表2 表别名2]|

[WHERE 条件(s)]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

SELECT * FROM emp NATURAL JOIN dept ;

USING字句

通过自然连接可以直接使用关联字段消除掉笛卡尔积,

如果现在的两张表中没有存在这种关联字段的话,就可以通过USING子句完成笛卡尔积的消除,

USING子句的语法如下所示:

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

FROM 表1 表别名 [JOIN 表2 USING(关联列名称)]|

[WHERE 条件(s)]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

USING子句,直接使用JOIN进行连接,同时指定关联的列

  • SELECT * FROM emp JOIN dept USING(deptno) ;

on字句

在之前编写等值连接时,采用了关联字段进行笛卡尔积的消除,那么用户在SQL:1999语法之中通过ON子句就可以由用户手工设置一个关联条件,ON子句语法:

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

FROM 表1 表别名1 [JOIN 表2 ON(关联条件)]|

[WHERE 条件(s)]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

ON子句,直接编写条件

  • SELECT * FROM emp e JOIN salgrade s

ON(e.sal BETWEEN s.losal AND s.hisal) ;

外连接

在数据的查询操作中数据的外连接一共分为三种形式:左外连接、右外连接、全外连接,而此时连接的语法如下:

SELECT [DISTINCT] * | 列名称 [AS] [列别名] , 列名称 [AS] [列别名] ,...

FROM 表1 表别名1 [LEFT|RIGHT|FULL OUTER JOIN 表2 ON(关联条件)]

[WHERE 条件(s)]

[ORDER BY 排序的字段1 ASC|DESC ,排序的字段2 ASC | DESC ..];

使用SQL:1999语法实现左外连接

  • SELECT *
  • FROM emp e LEFT OUTER JOIN dept d
  • ON (e.deptno=d.deptno) ;

使用SQL:1999语法实现右外连接

  • SELECT *
  • FROM emp e RIGHT OUTER JOIN dept d
  • ON (e.deptno=d.deptno) ;

使用SQL:1999语法实现全外连接

  • SELECT *

FROM emp e FULL OUTER JOIN dept d

ON (e.deptno=d.deptno) ;

五、数据的集合运算

数据的集合操作:UNION、UNION ALL、INTERSECT、MINUS

集合操作时,各个查询语句返回的结构要求一致

开发之中建议使用UNION来代替OR操作

SELECT * FROM emp WHERE job='SAL' OR job='CL';

SELECT * FROM emp WHERE job IN ('SAL' ,'CL');

SELECT * FROM emp WHERE job='SAL'

UNION

SELECT * FROM emp WHERE;OR job='CL';

集合运算是一种二目运算符,一共包括四种运算符:并、差、交、笛卡尔积

操作集合的语法如下所示:

查询语句

[UNION | UNION ALL | INTERSECT | MINUS]

查询语句

....

要实现集合的运算,主要使用四种运算符:

并操作是将多个查询的结果连接到一起,而对于并操作提供了两种操作符:UNION(不显示重复)、UNION ALL(显示重复)。

UNION(并集)

(不显示重复)

返回若干个查询结果的全部内容,但是重复元组不显示;

      • 将两个查询结果连接
        • 查询dept表的全部记录:SELECT * FROM dept ;
        • 查询10部门的详细记录:SELECT * FROM dept WHERE deptno=10 ;
      • UNION操作:
        • SELECT * FROM dept

UNION

SELECT * FROM dept WHERE deptno=10 ;

UNION ALL(并集)

(显示重复)

返回若干个查询结果的全部内容,重复元组也会显示;

      • UNION ALL操作:
        • SELECT * FROM dept

UNION ALL

SELECT * FROM dept WHERE deptno=10 ;

MINUS(差集):

返回若干个查询结果中的不同部分;

使用MINUS执行差集操作

  • SELECT * FROM dept

MINUS

SELECT * FROM dept WHERE deptno=10 ;

INTERSECT(交集):

返回若干个查询结果中的相同部分。

使用INTERSECT执行交集操作

  • SELECT * FROM dept

INTERSECT

SELECT * FROM dept WHERE deptno=10 ;

SQL Fundamentals || 多表查询(内连接,外连接(LEFT|RIGHT|FULL OUTER JOIN),自身关联,ON,USING,集合运算UNION)的更多相关文章

  1. 【SQL】多表查询中的 外连接 ,on,where

    先简单粗暴给个结论,多表连结查询中,on比where更早起作用,系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行匹配过滤,where后语句为真,则能查询出来,而通过外连接 ...

  2. mysql数据库中的多表查询(内连接,外连接,子查询)

    用两个表(a_table.b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接.外连接( 左(外)连接.右(外)连接.全(外)连接). MySQL版 ...

  3. 知识点:Oracle+表连接方式(内连接-外连接-自连接)+详解 来自百度文库

    Oracle 表之间的连接分为三种: 1. 内连接(自然连接) 2. 外连接 (1)左外连接 (左边的表不加限制)        (2)右外连接(右边的表不加限制)        (3)全外连接(左右 ...

  4. sql内连接外连接自然连接

    为什么我们要使用内连接和外连接呢?可以从两张或者多张表中找出,我们需要的属性. 这个比较好:http://www.cnblogs.com/youzhangjin/archive/2009/05/22/ ...

  5. SQL总结 连表查询

    连接查询包括合并.内连接.外连接和交叉连接,如果涉及多表查询,了解这些连接的特点很重要. 只有真正了解它们之间的区别,才能正确使用. 1.Union UNION 操作符用于合并两个或多个 SELECT ...

  6. 数据库SQL的多表查询

    数据库 SQL 的多表查询:eg: table1: employees, table2: departments,table3: salary_grades; 一:内连接: 1):等值连接: 把表em ...

  7. Python进阶----多表查询(内连,左连,右连), 子查询(in,带比较运算符)

    Python进阶----多表查询(内连,左连,右连), 子查询(in,带比较运算符) 一丶多表查询     多表连接查询的应用场景: ​         连接是关系数据库模型的主要特点,也是区别于其他 ...

  8. 基于ACCESS和ASP的SQL多个表查询与计算统计代码(一)

    近期在写几个关于"Project - Subitem - Task"的管理系统,说是系统还是有点夸大了,基本就是一个多表查询调用和insert.update的数据库操作.仅仅是出现 ...

  9. mysql,SQL标准,多表查询中内连接,外连接,自然连接等详解之查询结果集的笛卡尔积的演化

    先附上数据. CREATE TABLE `course` ( `cno` ) NOT NULL, `cname` ) CHARACTER SET utf8 NOT NULL, `ctime` ) NO ...

随机推荐

  1. CoreData数据库

        一  CoreData 了解 1 CoreData 数据持久化框架是 Cocoa API 的一部分,首先在iOSS5 版本的系统中出现:      它允许按照 实体-属性-值 模式组织数据: ...

  2. 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. JavaScript闭包——实现

    闭包的官方的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 通俗点的说法是: 从理论角度:所有的函数.因为它们都在创建的时候就将上层上下文 ...

  4. C# 时间戳

    C# 时间与时间戳互转 13位 /// <summary> /// 将c# DateTime时间格式转换为Unix时间戳格式 /// </summary> /// <pa ...

  5. Oracle执行计划——all_rows和first_rows(n) 优化器模式

    0. 环境创建 SQL> create usertest identified by test 2 default tablespace users 3 temporary tablespace ...

  6. jq屏蔽f5

    //屏蔽F5 $(document).ready(function () { $(document).bind("keydown", function (e) { e = wind ...

  7. Unity 发布的 WenGL 使用SendMessage传递多个参数

    如果要实现Unity与浏览器的数据交互一般都会采用两种方式 方法一: Application.ExternalCall("SayHello","helloworld&qu ...

  8. Linux修改日期、时间,系统与硬件时间

    Linux的时间分为两种,硬件时间和系统时间两种: 一.查看与修改系统时间 查看系统时间:date # date Fri Nov 26 15:20:18 CST 1999 用指定的格式显示系统时间:  ...

  9. 洛谷2860 [USACO06JAN]冗余路径Redundant Paths

    原题链接 题意实际上就是让你添加尽量少的边,使得每个点都在至少一个环上. 显然对于在一个边双连通分量里的点已经满足要求,所以可以用\(tarjan\)找边双并缩点. 对于缩点后的树,先讲下我自己的弱鸡 ...

  10. Mysql Explain的简单使用

    Mysql Explain 主要重要的字段有上面红色方框圈出来的那几个. type: 连接类型,一个好的SQL语句至少要达到range级别,杜绝出现all级别. key: 使用到的索引名,如果没有选择 ...