SQL多表查询

等值和不等值连接查询

  • 从多个表中获取数据:如果在查询的时候,直接从多个表中获取数据。没有添加条件判断,会出现“笛卡尔积”错误
  • 笛卡尔积错误
    • 笛卡尔集会在下面条件下产生

      • 省略连接条件
      • 连接条件无效
      • 所有表中的所有行互相连接
    • 为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件。
  • Oracle 连接多表查询
    • 在 WHERE 子句中写入连接条件。
    • 在表中有相同列时,在列名之前加上表名前缀
  1. SELECT table1.column, table2.column
  2. FROM table1, table2
  3. WHERE table1.column1 = table2.column2;
等值连接
  1. SELECT employees.employee_id, employees.last_name,
  2. employees.department_id, departments.department_id,
  3. departments.location_id
  4. FROM employees, departments
  5. WHERE employees.department_id = departments.department_id;
  • 区分重复的列名(使用表名或者表的别名)

    • 使用表名前缀在多个表中区分相同的列。
    • 在不同表中具有相同列名的列可以用表的别名加以区分。
  • 连接 n个表,至少需要 n-1个连接条件。 例如:连接三个表,至少需要两个连接条件。
  1. -- 练习:查询出公司员工的 last_name, department_name, city
  2. SELECT last_name, department_name, city
  3. FROM employees e ,departments d ,locations l
  4. WHERE e.department_id = d.department_id AND d.location_id = l.location_id
非等值连接
  1. -- EMPLOYEES表中的列工资应在JOB_GRADES表中的最高工资与最低工资之间
  2. SELECT e.last_name, e.salary, j.grade_level
  3. FROM employees e, job_grades j
  4. WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;

内连接、外连接(左(或右) 外连接、满外连接)

  • 内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
  • 外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL). 外连接的 WHERE 子句条件类似于内部连接, 但连接条件中没有匹配行的表的列后面要加外连接运算符, 即用圆括号括起来的加号(+).
内连接
  1. SELECT e.last_name, d.department_name
  2. FROM employees e, departments d
  3. WHERE e.department_id = d.department_id
  1. -- SQL1999语法的方式
  2. SELECT e.last_name, d.department_name
  3. FROM employees e
  4. INNER JOIN departments d ON e.department_id = d.department_id
外连语法
  • 使用外连接可以查询不满足连接条件的数据。

  • 外连接的符号是 (+)。

  • 右外连接

  1. SELECT table1.column, table2.column
  2. FROM table1, table2
  3. WHERE table1.column(+) = table2.column;
  4. -- 示例
  5. SELECT e.last_name, d.department_name
  6. FROM employees e, departments d
  7. WHERE e.department_id(+) = d.department_id
  8. -- SQL1999方式
  9. SELECT e.last_name, d.department_name
  10. FROM employees e RIGHT OUTER JOIN departments d
  11. ON (e.department_id = d.department_id)
  • 左外连接
  1. SELECT table1.column, table2.column
  2. FROM table1, table2
  3. WHERE table1.column = table2.column(+);
  4. -- 示例
  5. SELECT e.last_name, d.department_name
  6. FROM employees e, departments d
  7. WHERE e.department_id = d.department_id(+)
  8. -- SQL1999方式
  9. SELECT e.last_name, d.department_name
  10. FROM employees e LEFT OUTER JOIN departments d
  11. ON (e.department_id = d.department_id)
满外连接
  • 在SQL: 1999中,内连接只返回满足连接条件的数据
  • 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右) 外连接。
  • 两个表在连接过程中除了返回满足连接条件的行以外还返回两个表中不满足条件的行 ,这种连接称为满 外连接。
  1. -- 满外连接
  2. SELECT e.last_name, e.department_id, d.department_name
  3. FROM employees e
  4. FULL OUTER JOIN departments d
  5. ON (e.department_id = d.department_id)
自连接
  • 自连接可以把表本身作为连接的表
  1. -- 练习:查询出 last_name Chen 的员工的 manager 的信息
  2. SELECT worker.last_name || ' works for ' || manager.last_name
  3. FROM employees worker , employees manager
  4. WHERE worker.manager_id = manager.employee_id AND INITCAP(worker.last_name) = 'Chen'
叉集(了解)
  • 使用CROSS JOIN 子句使连接的表产生叉集。
  • 叉集和笛卡尔集是相同的。
  1. SELECT last_name, department_name
  2. FROM employees
  3. CROSS JOIN departments

自然连接

  • NATURAL JOIN 子句,会以两个表中具有相同名字的列为条件创建等值连接。
  • 在表中查询满足等值条件的数据。
  • 如果只是列名相同而数据类型不同,则会产生错误

返回的是,两个表中具有相同名字的列的“且、交集”,而非“或,并集”。即:比如employee类和department类都有

department_id和manager_id,返回二者都相同的结果。

  1. SELECT department_id, department_name,
  2. location_id, city
  3. FROM departments
  4. NATURAL JOIN locations

使用USING创建连接

  • 在NATURAL JOIN 子句创建等值连接时,可以使用 USING 子句指定等值连接中需要用到的列。
  • 使用 USING 可以在有多个列满足条件时进行选择。
  • 不要给选中的列中加上表名前缀或别名。
  • JOIN 和 USING 子句经常同时使用。
  • 有局限性:但若多表的连接列列名不同,此法不合适
  1. select last_name,department_name
  2. from employees
  3. join departments using (department_id);

使用ON 子句创建连接 (常用)

  • 自然连接中是以具有相同名字的列为连接条件的。
  • 可以使用 ON 子句指定额外的连接条件。
  • 这个连接条件是与其它条件分开的。
  • ON 子句使语句具有更高的易读性。
  1. SELECT e.employee_id, e.last_name, e.department_id,
  2. d.department_id, d.location_id
  3. FROM employees e JOIN departments d
  4. ON (e.department_id = d.department_id)
  5. -- 使用ON 创建多表连接
  6. SELECT employee_id, city, department_name
  7. FROM employees e
  8. JOIN departments d
  9. ON d.department_id = e.department_id
  10. JOIN locations l
  11. ON d.location_id = l.location_id

Oracle_多表查询的更多相关文章

  1. oracle_多表查询02

    多表查询 select * from BONUS; select * from DEPT; select * from EMP; select * from SALGRADE; BONUS表 ENAM ...

  2. django(3) 一对多跨表查询、ajax、多对多

    1.一对多跨表查询获取数据的三种形式:对象.字典.元组 例:有host与business两张表,host与business的id字段关联,business在host表中的对象名是b,  通过查询hos ...

  3. Mysql常用表操作 | 单表查询

    160905 常用表操作 1. mysql -u root -p 回车 输入密码   2. 显示数据库列表 show databases     3. 进入某数据库 use database data ...

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

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

  5. MyBatis实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  6. MyBatis学习总结(五)——实现关联表查询(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013516.html 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数 ...

  7. sql多表查询时怎么获取查到的字段

    首先,多表查询不能用hql(貌似hql就是不支持多表查询,如果可以,希望看到的朋友给个例子) List list = systemService.findListbySql("SELECT ...

  8. MyBatis入门学习教程-实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  9. 【T-SQL基础】01.单表查询-几道sql查询题

    概述: 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础 ...

随机推荐

  1. Linux下uniq命令的详解

           -c 在输出行前面加上每行在输入文件中出现的次数.  -d 仅显示重复行.       -u 仅显示不重复的行. 示例 1.去重,有多行一样的只显示一行cat 4.txt |sort - ...

  2. Github+Jekyll —— 创建个人免费博客(一)从零开始

    摘要: 本文中我将介绍一下如何在github上搭建个人Blog(博客),也顺便让我们掌握一下github Pages功能,另外还涉及到Jekyll技术. ======================= ...

  3. WIN32 窗口类封装 框架实现部分

    上面已经讲了窗口封装部分,内容可点击:http://www.cnblogs.com/mengdejun/p/4010320.html,下面分享框架部分内容,完成WINDOWS消息迭代 CQFrameW ...

  4. 跨域无法获取自定义header的问题

    同域的时候,header里面的参数可以随便自己定义.服务端都是可以获取的. 但是跨域的时候,除了设置 <add name="Access-Control-Allow-Origin&qu ...

  5. 谷歌浏览器允许ajax跨域以非安全模式打开

    最近使用ajax的时候,因为是在本地测试调用 后台时一直会报错. 解决方案:用谷歌浏览器 以非安全的模式打开 在cmd命令行中 cd 到谷歌的安装目录下 (右键 属性 复制路径) 然后在 运行如下命令 ...

  6. spring-data-jpa 方法名关键字的命名规范

  7. Html5选择本地视频音频文件播放

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Unity小游戏制作 - 暗影随行

    用Unity制作小游戏 - 暗影惊吓 最近玩了一个小游戏,叫做暗影惊吓,虽然是一个十分简单的小游戏,但是感觉还是十分有趣的.这里就用Unity来实现一个类似的游戏. 项目源码:DarkFollow 主 ...

  9. 如何生成报告来枚举出整个sharepoint环境中的每个页面所使用的所有webpart

    背景 我的公司的SharePoint环境中购买了大量的第三方webpart,比如Quick Apps, Telerik RadEditor, Nintex Workflow等等..这样做的好处就是成本 ...

  10. Response.StatusCode的HTTP状态代码列表

    1xx - 信息提示这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. · 100 - Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.( ...