--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 语法
原文:http://www.cnblogs.com/harveylv/p/6326619.html