多表查询

笛卡尔积

  • 左表的每条数据和右表的每条数据组合,这种效果称为笛卡尔乘积

select * from emp, dept;

  • 笛卡尔积引入了很多无用的数据,要完成多表查询,需要设置过滤条件来消除无用的数据

连接查询

  1. 从哪些表中查询数据
  2. 关联条件是什么
  3. 查询哪些字段

内连接查询

用左边表的记录去匹配右边表的记录,如果符合条件的则显示。如:从表.外键=主表.主键

1. 隐式内连接:使用where

-- 查询所有员工信息和对应的部门信息
select * from emp ,dept where emp.DEPTNO = dept.DEPTNO; -- 查询员工表的工号\姓名\部门名称
select emp.EMPNO,emp.ENAME,dept.DEPTNO,dept.DNAME
from emp ,dept
where emp.DEPTNO = dept.DEPTNO;

2. 显式内连接:使用inner join ... on ...

select 字段列表 from 表名1 [inner] join 表名2 on 条件

-- 将隐式内连接改成显示内连接

select emp.EMPNO,emp.ENAME,dept.DEPTNO,dept.DNAME
from emp
inner join dept
on emp.DEPTNO = dept.DEPTNO; select emp.EMPNO,emp.ENAME,dept.DEPTNO,dept.DNAME
from emp
join dept
on emp.DEPTNO = dept.DEPTNO;

外连接查询

1. 左外连接

用左边表的记录去匹配右边表的记录,如果符合条件的则显示;否则,显示 NULL
:在内连接的基础上保证左表的数据全部显示(左表是部门,右表员工)
select 字段列表 from 表1 left [outer] join 表2 on 条件; -- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
select emp.*,dept.DNAME from emp left OUTER join dept on emp.DEPTNO = dept.DEPTNO; -- 省略OUTER关键字
select emp.*,dept.DNAME from emp left join dept on emp.DEPTNO = dept.DEPTNO; -- mysql不支持 这种写法
select emp.*,dept.DNAME from emp , dept where emp.DEPTNO = dept.DEPTNO(+);

2. 右外连接

用右边表的记录去匹配左边表的记录,如果符合条件的则显示;否则,显示 NULL
:在内连接的基础上保证右表的数据全部显示
select 字段列表 from 表1 right [outer] join 表2 on 条件; -- 右连接
select emp.*,dept.DNAME from dept RIGHT OUTER join emp on emp.DEPTNO = dept.DEPTNO; select emp.*,dept.DNAME from dept RIGHT join emp on emp.DEPTNO = dept.DEPTNO; -- mysql不支持这种写法
select emp.*,dept.DNAME from emp , dept where emp.DEPTNO(+) = dept.DEPTNO;
-- 该sql仅用于演示右外连接写法 和上面2条sql 含义不一样

3.全外连接

全外 = 左外+右外+去重

-- 全外连接 mysql不支持

select emp.empno,emp.ename,emp.deptno,dept.deptno,dept.dname
from emp
full outer join dept
on emp.deptno = dept.deptno;

自连接

将一张表,通过别名“视为”不同的表

select e.ename 员工, b.ename 领导
from emp e,emp b
where e.mgr = b.empno ;

自连接不适合操作大表 层次查询

画层次图

oracle

select level,empno,ename,mgr from emp

connect by prior empno=mgr

start with mgr is null

order by 1;

子查询

查询中嵌套查询,称嵌套查询为子查询。

示例:查询工资比SCOTT高的员工信息
第一步:查SCOTT的工资
select sal from emp where ename='SCOTT';
第二步:查询比3000高的员工
select * from emp where sal > 3000; 子查询:子查询的查询结果,作为主查询的查询条件。
以上两步骤,合二为一:
select * from emp where sal > ( select sal from emp where ename='SCOTT' );

子查询注意:

a.子查询可以出现的位置:where、select、having、from ;不能出现在group by后面。

b. 主查询和子查询可以不是同一张表

e. 一般不在子查询中排序;但在Top-N分析问题中,必须对子查询排序

子查询中的null

not in不能有null

not in (10,20,null)

示例:查询是老板的员工信息

select * from emp where empno not in (select mgr from emp);

必须排空: (select mgr from emp where mgr is not null)

子查询不同情况

1. 子查询的结果是单行单列的
可以作为条件,使用运算符去判断 运算符: > >= < <= =
也可以使用在 select 后 或 having后 -- 查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.sal < (SELECT AVG(sal) FROM emp); 2. 子查询的结果是 *多行单列* 的
可以作为条件,使用多行运算符来判断 in
-- 查询'SALES'和'OPERATIONS'所有的员工信息
SELECT * FROM emp WHERE deptno IN (SELECT deptno FROM dept WHERE dNAME = 'SALES' OR dNAME = 'OPERATIONS'); 子查询中的运算符 any、all any: 和集合中任意一个值比较
查询工资比30号部门其中一个员工高的员工信息
select * from emp where sal > any (select sal from emp where deptno=30);
等价于 > (select min(sal) from …) all: 和集合中的所有值比较
查询工资比30号部门所有员工高的员工信息
select * from emp where sal > all (select sal from emp where deptno=30);
等价于 > (select max(sal) from…) 3. 子查询的结果是多行多列的
可以作为一张虚拟表参与查询 -- 查询员工入职日期是1986-11-11日之后的员工信息和部门信息
-- 子查询
SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.hiredate > '1986-11-11') t2 WHERE t1.deptno = t2.deptno; -- 注意oracle和mysql日期格式区别 oracle:'11-11月-86' -- 可以改写成普通内连接

集合

  • union:并集,返回各个查询的所有记录,重复部分,只出现一次
  • union all:并集,返回各个查询的所有记录,重复部分 不受影响
  • intersect,交集:返回两个集合 共用的记录。
  • minus,补集:返回 包含在第一个查询集合中,但同时不包含在第二个查询集合中的记录。
-- intersect 和 minus mysql不支持

select * from emp where deptno =10
union
select * from emp where deptno =20; select * from emp where deptno =10
union all
select * from emp where deptno =20; select * from emp where deptno != 10
intersect
select * from emp where deptno =20; select * from emp where deptno !=10
minus
select * from emp where deptno =20;

sql-DQL-多表联查的更多相关文章

  1. mybatis-plus注解版实现多表联查(sql)

    mybatis注解版实现多表联查 需求: 用户有角色,角色有权限,需要一次取用户信息包含角色信息及其对应权限 实体类: package cn.zytao.taosir.common.model.use ...

  2. mybatis.net 多表联查

    mybatis.net针对多表联查,其实不用讲联查出的所有的列全部做一个新的resultMap,我们完全可以通过集成关系来实现,真是上一次说的懒加载,在一定程度上可以提高其性能,但这并不是说懒加载性能 ...

  3. asp.net mvc 三层加EF两表联查

    首先打开vs软件新建项目创建web中的mvc项目再右击解决方案创建类库项目分别创建DAL层和BLL层再把DAL层和BLL层的类重命名在mvc项目中的Models文件夹创建model类在DAL创建ADO ...

  4. SQLServer多表联查,多表分页查询

    多表联查: select p.*,s.Sheng , i.Shifrom  [dbo].[ProductRecordInfo]   --表名 p left join [ShengInfo] s on ...

  5. [工作日志] 2018-11-30 重要: 1. 多条件+ 分页 + 多表联查 2. idea拉新分支

    多条件+ 分页 + 多表联查 多条件查询 1.pom依赖 <dependency> <groupId>commons-dbutils</groupId> <a ...

  6. .NET MVC+ EF+调用存储过程 多表联查以及VIEW列表显示

    直接上干活,至于网上的一大堆处理方式不予评论,做好自己的就是最好的,供大家不走弯路 1.view页面 <link href="~/Content/bootstrap.css" ...

  7. Sql 2000系统表 语句查询表结构

     SQL2000系统表的应用  –1:获取当前数据库中的所有用户表 select Name from sysobjects where xtype=’u’ and status>=0 –2:获取 ...

  8. DQL多表查询

    DQL多表查询 一.多表查询实现多个表之间查询数据 1.交叉连接笛卡尔积:A表中的每一行匹配B表中的每一行基本结构:select [数据库名1.]表名1,属性名1,......, [数据库名.]表名. ...

  9. Mybatis中多表联查,查询出来的字段出现重名,造成数据异常的解决方法!

    在做一对多出现的问题,引发的思考:当数据库表中,主表的主键id和明细表的中的字段名相同时怎么办?Mybatis进行自动映射赋值的时候会不会出现异常?                      注意:M ...

  10. 你真的会玩SQL吗?表表达式,排名函数

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

随机推荐

  1. NodeJs学习日报day9——操作数据库

    const mysql = require('mysql') const db = mysql.createPool({ // 数据库的ip地址 host: 'localhost', user: 'r ...

  2. 约定编程与Sping AOP

    一.约定编程 Spring AOP是一种约定流程的编程,咱们可以先通过动态代理模式的实现来理解Spring AOP的概念. 代理的逻辑很简单,例如,当你需要采访一名儿童时,首先需要经过他父母的同意,在 ...

  3. c#中判断类是否继承于泛型基类

    在c#中,有时候我们会编写类似这样的代码: public class a<T> { //具体类的实现 } public class b : a<string>{} 如果b继承a ...

  4. 2021.08.05 P7095 不离【扶咕咕出题】(贪心)

    2021.08.05 P7095 不离[扶咕咕出题](贪心) [P7095 yLOI2020] 不离 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 游戏中人物有两个属性,我 ...

  5. MySQL Router重装后重新连接集群进行引导出现的——此主机中之前已配置过的问题

    问题出现的前因: 因为重新安装了MySQL Router,然后打算重新连接上目标集群进行MySQL Router的初始化引导,结果报错了! [root@linux666 system]# mysqlr ...

  6. 程序员延寿指南「GitHub 热点速览 v.22.17」

    很多人对程序员的固有印象之一便是常加班.易"猝死"!近几年的许多报道似乎也进一步加深了这种印象.应该如何更好地健康地活着.敲喜欢的代码呢?HowToLiveLonger 教你如何从 ...

  7. 在jupyterlab中实现实时协同功能

    1 简介 当你在使用jupyter时,有没有想象过如果我们可以把正在编写代码的jupyter界面共享给其他人,使得别人可以在其他地方实时看到与你同步的jupyter界面,这样一来无论是与他人沟通代码逻 ...

  8. python数据可视化-matplotlib入门(6)-从文件中加载数据

    前几篇都是手动录入或随机函数产生的数据.实际有许多类型的文件,以及许多方法,用它们从文件中提取数据来图形化. 比如之前python基础(12)介绍打开文件的方式,可直接读取文件中的数据,扩大了我们的数 ...

  9. c++:-1

    C++第一部分介绍基础:c++:-0,本节介绍C++中函数使用. 函数 函数调用 调用函数需要先声明函数原型 嵌套调用: 参数传递 在函数被调用时才分配形参的存储单元 实参可以是常量.变量或表达式 实 ...

  10. 面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!

    大家好,我是老三,面渣逆袭系列继续,这节我们来搞定Redis--不会有人假期玩去了吧?不会吧? 基础 1.说说什么是Redis? Redis是一种基于键值对(key-value)的NoSQL数据库. ...