zoukankan      html  css  js  c++  java
  • mysql-6多表查询(连表查询、子查询、limit分页查询)

    6.多表查询

    a.连接查询

    1.连接查询

    • 1.1多表连接,跨表查询

    • 1.2分类:sql92,sql99

    • 1.3 表连接分类:

      • 内连接:等值连接、非等值连接、自连接,
      • 外连接:左外连接(左连接)、右外连接(右连接),
      • 全连接

    2.笛卡尔积

    当两张表进行连接查询,没有任何条件限制的,最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积

    select ename,dname from emp,dept;
    
    • 1.5如何避免笛卡尔积现象 (sql92语法)

    • 虽然使用where 进行条件筛选,但是并没有减少匹配此次

    • 表的连接次数越多,效率越低,尽量避免表的连接

      select ename,dname from emp,dept where emp.deptno=dept.deptno; 通过设定条件(sql92语法)
      
      -- 优化
      select emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;
      
      -- 使用别名进行进一步优化,提供效率
      select e.ename,d.dname from emp e,dept d  where e.deptno= d.deptno;
      
    

    3.内连接- 等值连接(条件是等量关系故称等值连接) inner

    案例:查询每个员工所在部门名称,显示员工名和部门名

    emp e 和dep d 表进行连接。条件是e.deptno = d.deptno

    -- sql 92语法
    select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno
    
    -- sql 99语法 join 前inner 可省略
    select 
    	e.ename,d.dname 
    from 
    	emp e 
    join 
    	dept d 
    on 
    	e.deptno= d.deptno;
    
    
    • sql92缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放在where后面
    • sql99优点:表连接的条件是独立的,连接之后,如果还需进一步筛选,再往后继续添加where

    4.内连接- 非等值连接

    条件不是一个等量关系,称为非等值连接

    范围、等级、取值区间关联,使用between.. and..

    -- between .. and 
    select 
    	e.ename,e.sal,s.grade
    from
    	emp e
    join
    	salgrade s
    on 	
    	e.sal between s.losal and s.hisal;
    

    5.内连接 -自连接

    技巧:把一张表,看成两张表

    对emp 领导表内进行自连接,需要把emp 表既看成员工表,也看成领导表

    empno ename mgr
    7369 smith 7902
    7499 allen 7698
    7698 blark 7839
    7902 ford 7566
    -- 
    select 
    	a.ename as '员工名', b.ename as'领导名'
    from 
    	emp a
    join 
    	emp b
    on 
    	a.mgr=b.empno;  
    --  员工的领导编号 = 领导的员工编号
    

    6.外连接

    • 右外连接 right join

      ​ 右表为主表,将右表全部查询出来,捎带关联左边的表

      ​ 在外链接当中,两张表连接,产生了主次关系。

    • 左外连接亦然 left join

    -- 右外连接
    -- 可带outer 带上可读性更强
    select 
    	e.ename,d.dname 
    from 
    	emp e 
    right  outer join   
    	dept d  -- 右边全部匹配
    on 
    	e.deptno= d.deptno;
    

    总结 外连接的查询结果条数一定是>=内连接的查询结果条数

    7.三张表,四张表连接

    -- 语法:
    select 
     ... 
    from 
    	a
    join 
    	b
    on 
    	a和b的连接条件
    join 
    	c
    on 
     	a和c的条件
    join 
    	d
    on 
    	a和d的条件
    -- 一条sql中内连接和外连接可以混合,都可以出现
    

    案例:

    找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级

    如果再加上查询员工的上级领导(使用外连接,避免删除)

    分析:从emp 取出ename, 关联dept,取dname, 关联salgrade 取grade

    emp
    empno ename sal depton
    7398 smith 800.00 20
    7499 allen 1600.00 30
    7521 ward 1250.00 30
    7654 martin 1250.00 30
    dept
    deptno dname loc
    10 accounting new york
    20 research dallas
    30 sales chicago
    40 operations boston
    salgrde
    grade losal hisal
    1 700 1200
    2 1201 1400
    3 1401 2000
    4 2001 3000
    select e.ename,d.dname,s.grade
    from emp e 
    join dept d 
    on  e.depton = d.depton.deptno
    join salgrade s
    on  e.sal between s.losal and  s.hisal;
    

    b.子查询

    1.子查询

    select 语句中嵌套select 语句,被嵌套的select 的语句称为子查询

    2.where 条件后的子查询

    -- 子查询1,where条件中
    select 表头a from 表a  where  表头  ..   (select .. from table_b)
    

    3.from 子语句中的子查询 (可以将子查询的结果当做一张临时表)

    -- from 子句中的子查询
    from 后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)
    

    __注意__子查询注意分组函数的使用时易被错认为函数,导致报错,需要对该分组函数命名

    4.select 后面出现的子查询

    select 按表行搜索,类似循环嵌套,(使用联表进行查询)

    • select 后面出现的子查询只能返回一条结果,多于一条报错

      -- 实例
      理解: 查询emp表,分别查询e对应的ename列,deptno列,以及e第一行中对应的deptno 对应d表中的dname,
      select 
      	e.ename,e,deptno (select d.dname from dept d where e.deptno=d.deptno) as dname 
      from 
      	emp e;
      
    • 实例 查询各科成绩前三名的记录:(不考虑成绩并列情况)

    select score.sid,score.course_id,score.num,T.first_num,T.second_num from score left join
     (select
            sid,
            (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num,
            (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 3,1) as second_num
        from
            score as s1
        ) as T
        on score.sid =T.sid
        where score.num <= T.first_num and score.num >= T.second_num;
    

    c.union 合并查询结果集

    • union 进行结果集合并要求结果集的列数相同,合并时列与列的数据类型也相同
    • 同时union合并时会自动去重,可以使用union all 进行保留
    • 减少匹配次数,实现数据集的拼接
    • union的效率要高一些(减少匹配次数),对于表连接而言,每连接一次新表,则匹配的次数满足笛卡尔积
    • 实例:

    ​ 查询工作岗位是manager 和salesman的员工

    -- 第一种
    select ename,job from emp where job='manager' or 'salesman';
    
    -- 第二种
    select ename,job from emp where job in ('manager','salesman');
    
    • 使用union 进行合并
    select ename,job from emp where  job ='manager'
    union
    select ename,job from emp where job = 'salesman';
    

    D、limit 分页查询

    1.将数据集的一部分取出,通常使用在分页查询当中

    • 语法

      完整用法:limit  startindex,length 
      		startindex	 起始下标  length 长度
      		起始下标从0开始
      		
      缺省用法:limit num; 取前num个
      		limit 8  表示取前八个
      		
      
    • limit 与oder by的使用

      select ... from...
      order by  .. desc  limit 5
      

    2.通用分页

    • 每页显示3条记录
      • 第1页 : limit 0,3
      • 第2页: limit 3,3
      • 第3页: limit 6,3
      • 第4页: limit 9,3
      • 第n页: limit (num-1)*3,3
  • 相关阅读:
    android平台从froyo 2.2开始支持jni单步调试
    Ubuntu java 环境变量
    ubuntu 10.04安装sunjava5jdk
    proc文件系统usb部分信息输出
    Linux lftp乱码解决及使用书签的方法
    用find & grep查找文件内容
    ubuntu10.10 下安装android 2.2开发环境
    VIM复制粘贴大全!
    kinect 无法在我的android开发板上显示的分析
    hdu 1087 Super Jumping! Jumping! Jumping!
  • 原文地址:https://www.cnblogs.com/yescarf/p/14095688.html
Copyright © 2011-2022 走看看