SQLServer 子查询

1、简单子查询
select ename,deptno,sal
from emp
where deptno=(select deptno from dept where loc='NEW YORK');  
查询结果作为一列出现在数据表中
--子查询的查询结果作为SELECT 子句的列
select 名字,性别,工资,所属部门,
(select AVG(工资) from mar) as 平均工资 ,
(工资-(select AVG(工资) from mar)) as 与平均工资的差额
from mar  
SQLServer 子查询_第1张图片
运行结果:
  SQLServer 子查询_第2张图片
--查询学生成绩大于平均成绩的记录
select 语文,英语,数学,代数,name as 名字,sex as 性别,class as 班级,SUM(语文+英语+数学+代数) as 总分
from tb_stuAchievement
where (语文+英语+数学+代数)>(select AVG(语文+英语+数学+代数) from tb_stuAchievement)
group by 语文,英语,数学,代数,name ,sex,class  
查询的结果:

子查询作为 FROM 子句的查询依据
实现在挂账明细数据表(tb_gzmx)中查询排名第三的挂账单位即总计金额
--子查询作为FROM 子句的查询依据
select top 1 * 
from(select top 3 挂账单位,SUM(欠款金额)as 金额
        FROM tb_gzmx
        GROUP BY 挂账单位 
        ORDER BY 金额 desc) tb1
ORDER BY 金额   

 
2、 多列子查询
SELECT deptno,ename,job,sal
FROM EMP
WHERE(deptno,sal) IN (SELECT
            deptno,MAX(sal)
            FROM EMP
            GROUP BY deptno);  
3、 多行子查询
SELECT ename,job,sal
FROM EMP
WHERE deptno in ( SELECT deptno FROM dept WHERE dname LIKE 'A%');  

--多行子查询
--查询外语成绩大于某值的学生明细信息
SELECT 学生编号 
FROM tb_Student 
WHERE 外语>80
--查询大于学生的全部信息(IN)
select 学生名字,所在学院,家庭住址
from tb_StuInfo
where 学生编号 in (select 学生编号 
                        from tb_Student    
                        where 外语>80)
                        
--返回月销售不在同类图书前100 名的图书信息(NOT IN)
select * 
from tb_BookInfo
where 书号 not in (select 书号 
                        from tb_BookOrder
                        where 同类图书排名<100)
                        
--显示一班学生总成绩大于二班所有学生总成绩的学生信息(ALL)
select 学生编号,学生姓名,总分
from tb_stuAchievement
where 总分>ALL(
        select 总分    
        from tb_stuAchievement
        where 班级='二班')
    and
    班级='一班'
   
--查询商品三月份销售额大于当月同类平均销售额的商品信息(ANY/SOME)
select 商品编号,所属类型,商品等级,商品名称,三月
from tb_商品销售
where 三月>ANY(
        select AVG(三月)
        from tb_商品销售
        GROUP BY 所属类型,商品等级)
        
ANY 的意义和用法
    >ANY 表示至少大于条件中的一个值,或一句话说,大于最小值。如 >ANY(1,2,3) 表示 >1
    要使用带有 >ANY 的子查询表示要使用某一行满足外部查询中指定的值,引入子查询的列中的值必须至少大于由
    子查询返回的值的列表中的一个值。  
4、 内联视图子查询
(1)SELECT ename,job,sal,rownum
          FROM (SELECT ename,job,sal FROM EMP ORDER BY sal);
(2)SELECT ename,job,sal,rownum
          FROM ( SELECT ename,job,sal FROM EMP ORDER BY sal)
          WHERE rownum<=5;  
5、 在HAVING子句中使用子查询
SELECT deptno,job,AVG(sal) FROM EMP GROUP BY deptno,job HAVING AVG(sal)>(SELECT sal FROM EMP WHERE ename='MARTIN');  

在 HAVING 子句使用查询过滤一组数据
技术要点:
        HAVING,WHERE,GROUP BY 子句的正确序列对编写高效的查询代码会有所帮助,他们 3 个应用的具体含义如下:
            ·WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行;
            ·GROUP BY 子句用来分组 WHERE 子句的输出;
            ·HAVING 子句用来从分组的结果中筛选行。

例子: 应用 HAVING 关键字进行分组查询,首先通过 GROUP BY 对公司员工表 中的人名和年龄进行分组查询,之后通过 HAVING 执行分组的查询条件,其中,通过子查询计算员工的平均年龄。
select 人员姓名,年龄
from tb_aMRen
group by 人员姓名,年龄
having 年龄>(select avg(年龄) from tb_aMRen)  
6、 相关子查询
       相关子查询指的是查询中再查询,通常是以一个查询作为条件来供另一个查询使用1>非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。 相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。
例子:求出部门内职员工资最高的职员信息(IN)
在职员工资表 (tb_treatment)和职员信息表 (tb_employee) 中查询部门内职员工资最高的职员信息
select b.姓名,b.部门,a.salary,b.业绩
form tb_treatment as a ,tb_employee as b
where a.salary in (
        select max(salary)
        from tb_treatment    
        where a.name = b.姓名
        group by dept
)  
例子:查询图书销量大于某值得图书信息 ( EXISTS) 
利用 EXISTS 谓词在图书信息表 (tb_BookInfo) 和图书销量排名表 (tb_BookOrder) 中查询图书销量大于 400 册的图书信息
select *
from tb_BookInfo as  a
where exists(
        select * 
        from tb_BookOrder as b
        where a.书号 = b.书号
            and 
                销售数量 > 400
)  
例子:返回商品采购量不小于某值得商品销售信息 (NOT EXISTS)
利用 NOT  EXISTS 谓词在商品采购信息表 (tb_商品采购)和 商品销售表 (tb_商品销售) 中查询采购量不小于 2000 (即大于或等于2000)的商品销售信息
select *
from tb_商品销售 as  a
where mot exists (select *
                                from tb_商品采购 as b
                                where a.商品编号 = b.商品编号
                                                and 采购量 < 2000
)  

注意,使用 EXISTS 引入的子查询在下列方面与其他子查询略有不同:

  • EXISTS 关键字前面没有列名、常量或其他表达式。
  • 由 EXISTS 引入的子查询的选择列表通常几乎都是由星号 (*) 组成。由于只是测试是否存在符合子查询中指定条件的行,因此不必列出列名。 

由于通常没有备选的、非子查询的表示法,因此 EXISTS 关键字很重要。尽管一些使用 EXISTS 创建的查询不能以任何其他方法表示,但许多查询都可以使用 IN 或者由 ANY 或 ALL 修改的比较运算符来获取类似结果。


7、 嵌套子查询
    在  WHERE  子句中可以嵌套 SQL 语句。可以使用 IN,ALL , SOME/ANY 等关键字引入嵌套的 SQL 语句。使用嵌套查询可以使用一个复杂的查询分解成一系列的逻辑步骤,使语句的思路更加清晰。

例子:查询指定学历的部门经理当月工资情况
在 人员表(tb_aMRem),部门表(tb_MRDe),工资表(tb_MRPay),这 3 个表中查询学历是本科的部门经理的 2008 年 10 月份工资情况。
select *
from tb_aMRPay
where 工资月份=10
    and 人员姓名 in(
        select 负责人
        from tb_aMRDe
        where 负责人 in(
            select 人员姓名
            from tb_aMRem
            where 学历='本科'))
order by 人员编号  

例子:返回学科成绩小于指定的多个成绩任意一个的学生信息
    在学生成绩表(tb_StuMark)中查询软件工程课程成绩小于学生编号从 "200941004"到"200941005"的任何一个学生该们课程成绩的学生信息
select *
from tb_StuMark
where 软件工程 < some(
    select 软件工程
    from tb_StuMark
    where 学生编号 in(
        select 学生编号
        from tb_StuMark
        where 学生编号 between 200941004 and 200941006))  
8、 在 UPDATE 语句中使用子查询更新数据
例子:
在 UPDATE 语句的 SET 子句中,利用子查询返回药品登记表中与药品销售表药品编号对应的药品名称,并为药品销售表中的药品名称赋值
update tb_药品销售
set 药品名称=(select 药品名称
                                from tb_药品登记
                                where tb_药品销售.药品编号=tb_药品登记.药品编号)  
9、 在 INSERT INTO 语句中使用子查询添加数据
例子:
  通过子查询将药品登记表(tb_药品登记)中存在而药品销售表(tb_药品销售)不存在的记录插入到药品销售表。
        insert into tb_药品销售(药品编号,药品名称)
        (
                 select 药品编号,药品名称
                    from tb_药品登记
                    where 药品编号 NOT IN (
                            select 药品编号
                            from tb_药品销售
                       )       
           )  
10、 在 DELETE 语句中使用子查询删除数据
例子:
通过查询药品登记表(tb_药品登记),删除药品销售表(tb_药品销售)中药品生产厂家为 "长春一通" 的药品销售信息
delete tb_药品销售
where 药品编号 IN(
    select 药品厂家 
    from tb_药品登记
    where 生产厂家 LIKE '%长春一通%'
)  

你可能感兴趣的:(数据库,SQLServer,SQL)