zoukankan      html  css  js  c++  java
  • 013.子查询和分页子查询(sql实例)

    --1 子查询
    如果子查询和表连接都实现的时候,推荐用表连接实现(
    一般:能用表连接实现的就用表连接,有些情况用表连接不能
    或者不易实现的再选择子查询)
    系统:缓存,执行计划技术手段

    --1 where 条件后 + 子查询

    注意: 1 先执行的是子查询语句
    2 子查询嵌套的层数越大,性能会随之递减

    A) 当子查询写在比较运算符之后(=,!=,>,...)时
    要求:子查询的查询结果不能多于1个(1,0(不会报错,
    没有结果))
    --eg
    select * from EMP
    where SAL>(select sal from emp where EMPNO=7369 )
    B) 当子查询的查询结果多于1个的时候,
    使用 in,exists 存在, 关键字

    -----------------------------------------
    --in子查询
    --查询工作部门是销售部,研发部的员工
    select * from EMP
    where DEPTNO in(
    select deptno from DEPT
    where DNAME='sales' or DNAME='research')

    思考:in子查询不适合子查询的查询结果特别多的情况

    --eg : 查询有员工的部门,并显示部门信息。
    --1 表连接
    select d.* from EMP e,DEPT d
    where e.DEPTNO=d.DEPTNO

    --查询没有员工的部门 (下面的语句是获取不到的)
    select d.* from EMP e,DEPT d
    where e.DEPTNO!=d.DEPTNO --(笛卡尔积-相等的)

    --2 子查询查询没有员工的部门
    select * from DEPT
    where DEPTNO not in(
    select distinct DEPTNO from EMP)
    思考: not in 是所有子查询中效率最差的,所以能
    少用就少用。
    --------------------------------------------
    --exists 子查询
    exists(select) 返回 boolean
    判断查询结果是否存在 (select * from EMP
    where DEPTNO=10 )true ,false
    短路的行为:查询语句不需要执行出查询结果的,一旦
    查询条件为true,那么select语句就结束,exists就返回true

    --常见应用

    --自动
    --思路:
    --如果有此数据库
    if(exists(select name from sysdatabases where
    name='testdb'))
    drop database testdb --先删除

    create database testdb -- 创建
    ---------------------------------------------
    创建表 :自动化(如果有此表,删除再创建,
    否则直接创建)
    select * from sysobjects where name='tab'
    if (not exists( select * from sysobjects
    where name='tab'))
    create table tab(id int ,name varchar(20))
    else
    begin
    drop table tab
    create table tab(id int ,name varchar(20))
    end

    -- 查询有员工的部门,并显示部门信息。
    --exists 子查询

    select * from DEPT
    where exists(select * from EMP
    where DEPTNO=DEPT.DEPTNO )
    思考:
    exists 不适合的是外部查询的数据量巨大
    in 不适合子查询的数据量巨大
    not in 是效率的最差的子查询
    当外部查询与子查询数据量相当的时候in,exists
    子查询的效率也相差不大。

    -- EG:用子查询实现,查询emp表中的第6到第10个员工
    --(分页的基础)(特别提醒:员工编号唯一,但不一定连续)
    --不考虑效率 in 子查询

    select top 5 * from EMP
    where EMPNO not in(select top 5 EMPNO from emp)


    -------------------------------------
    --2 在from 之后使用子查询(数据来源)
    select from 表|视图|结果集(子查询)
    --eg:查询所有销售部工作的员工信息
    select 部门名称,ename from(select ENAME,SAL,JOB,DNAME 部门名称 ,
    LOC部门所在地
    from EMP,DEPT
    where EMP.DEPTNO=DEPT.DEPTNO)as t --必须有别名
    where 部门名称 ='sales'
    ----------------------------------------
    --3 在增删改操作中嵌入子查询的案例
    --A)insert +select
    1) 增加多行
    insert into tab_name....
    select * union
    select * union
    select ...
    2) 向现有表备份数据
    insert into new_tab
    select * from old_tab
    --B) update +select

    --eg1 员工smith要调换工作部门到 销售部(sales),
    --编写修改语句实现smith的工作调转

    update EMP set DEPTNO=(select deptno from DEPT
    where DNAME='sales')
    where ENAME='smith'

    --C) delete +select

    --eg2 删除所有研发部的员工(研发部的部门名称是
    --research)
    delete from EMP
    where DEPTNO=(select deptno from DEPT
    where DNAME='research')

    --综合练习:分页查询

    用子查询实现,查询emp表中的第6到第10个员工
    (分页的基础)(特别提醒:员工编号唯一,但不一定连续)
    --不考虑效率 in 子查询
    --效率低

    select top 5 * from EMP
    where EMPNO not in(select top 5 EMPNO from emp)

    --效率更好的 分页子查询(row_number)
    开窗函数: row_number()over(排序是由需求决定的)
    生成有序结果集并添加行号列。

    select * from
    (select ROW_NUMBER() over(order by empno desc)as 行号,
    * from EMP ) t
    where 行号 between 6 and 10


    ---------t_sql 语法

    关注90後梦想大师,梦想从未止步.
  • 相关阅读:
    HDU5087——Revenge of LIS II(BestCoder Round #16)
    HDU5086——Revenge of Segment Tree(BestCoder Round #16)
    POJ3009——Curling 2.0(DFS)
    POJ2891——Strange Way to Express Integers(模线性方程组)
    算法总结之求解模线性方程组
    Linux运维学习笔记-网络技术知识体系总结
    Linux运维学习笔记-定时任务知识总结
    Linux运维学习笔记-文件权限知识总结
    Linux运维学习笔记-常用快捷键及vi、vim总结
    Linux运维学习笔记-角色知识总结
  • 原文地址:https://www.cnblogs.com/harveylv/p/6326619.html
Copyright © 2011-2022 走看看