zoukankan      html  css  js  c++  java
  • SQL查询(交、并、子查询、开窗函数……)

    • 1 select * from scores

    • 使用TOP限制结果集,WITH TIES作用-包括最后一行取值并列的结果
      1 --查询english最高的前3名
      2 select top 3 with ties id,chinese,math,english
      3 from scores 
      4 order by english desc

      1 --查询出现次数最多的chinese分数值
      2 select top 1 with ties chinese, count(*) as 次数 --COUNT()需要和group by一起使用
      3 from scores
      4 group by chinese
      5 order by count(*) desc




      1 --查询总成绩前20%学生成绩
      2 select top 20 percent with ties id, chinese, math, english, chinese+math+english as total
      3 from scores 
      4 order by chinese+math+english desc

    • 1 select  id, chinese, math, english, chinese+math+english as total, level = 
      2 case
      3     when chinese+math+english > 270 then 'A'
      4     when chinese+math+english > 230 then 'B'
      5     else 'C'
      6 end
      7 from scores 
      8 order by chinese+math+english desc

    •  1 --将查询结果保存到新表中
       2 --使用'#'将新表标识临时表,生存期与创建此局部临时表的用户的连接生存期相同,只在当前连接中使用
       3 --使用'##'将新表标识全局临时表,生存期与创建此局部临时表的用户的连接生存期相同,可被所有的连接使用
       4 --将上一步查询的结果存入新表
       5 select  id, chinese, math, english, chinese+math+english as total, level = 
       6 case
       7     when chinese+math+english > 270 then 'A'
       8     when chinese+math+english > 230 then 'B'
       9     else 'C'
      10 end
      11 into global_scores --全局新表
      12 from scores 
      13 order by chinese+math+english desc
      14 go 
      15 select * from global_scores



      1 --在永久表中查询level为B的学生
      2 select * from global_scores
      3 where level = 'B'



       1 --将查询结果保存到新表中
       2 --使用'#'将新表标识临时表,生存期与创建此局部临时表的用户的连接生存期相同,只在当前连接中使用
       3 --使用'##'将新表标识全局临时表,生存期与创建此局部临时表的用户的连接生存期相同,可被所有的连接使用
       4 --将上一步查询的结果存入新表
       5 select  id, chinese, math, english, chinese+math+english as total, level = 
       6 case
       7     when chinese+math+english > 270 then 'A'
       8     when chinese+math+english > 230 then 'B'
       9     else 'C'
      10 end
      11 into #temp_scores --临时表
      12 from scores 
      13 order by chinese+math+english desc
      14 go 
      15 select * from  #temp_scores --可像永久表一样查询
      16 where level = 'B'

    • 并运算UNION
      1 select * from global_scores
      2 where level = 'B'
      3 union
      4 select * from global_scores
      5 where level = '

    • 交运算INTERSECT
      1 select * from scores where chinese = 95
      2 intersect
      3 select * from scores where math = 64

    • 差运算EXCEPT
      select * from scores where chinese = 95

      1 select * from scores where chinese = 95
      2 intersect
      3 select * from scores where math = 64
    • 使用子查询进行基于集合的测试
      1 --子查询,查询与id为2的学生chinese成绩相同的学生
      2 select * from scores
      3 where chinese in
      4 (
      5     select chinese from scores where id = 2
      6 )
      7 and id != 2

    • 使用子查询进行比较测试
    • 1 --查询成绩最高的
      2 select *, chinese+math+english as total
      3 from scores where chinese+math+english =
      4 (
      5     select MAX(chinese+math+english) from scores
      6 )

      1 --查询成绩高与平均分的学生
      2 select *, chinese +math + english as total from scores
      3 where chinese + math + english >
      4 (
      5     select AVG(chinese +math + english) from scores
      6 )

    •  使用子查询进行存在性测试

      1 select * from info

      1 --查询名字为'd'的学生成绩
      2 select * from scores 
      3 where exists
      4 (
      5     select * from info where scores.id = info.id and info.name = 'd'
      6 )


      以下情况起不到选择作用,会返回所有结果

      1 select * from scores 
      2 where exists
      3 (
      4     select * from scores where chinese > 80
      5 )


      改成这样则可以,可能因为子查询只查一个表的时候,会导致exists返回的值总是true或总是false的情况(对于每一层外查询,exists内执行的子查询是一样的),而与外查询中的表连接后,因为每一层外查询对应的值不同,所以每一次执行的子查询结果都不同,exists会有true或false,达到选择的目的

      如上面一个查询语句中的select * from scores where chinese > 80,该语句总是true,因为一直存在>80的数据,而对于下面这一查询语句因为外查询是一行一行查的,对于每一行外查询,它的id值都是不同的(依次为1,2,3,4……),所以子查询中select * from scores b where a.id = b.id and chinese > 80,条件:a.id = b.id并没有一直成立,所以可能返回true或false

      1 select * from scores a 
      2 where exists
      3 (
      4     select * from scores b where a.id = b.id and chinese > 80
      5 )



      以下数据库数据借用:https://blog.csdn.net/mrbcy/article/details/68965271

    • 替代表达式的子查询

       1 --替代表达式的子查询是指在SELECT语句的选择列表中嵌入一个只返回一个标量值的SELECT语句,这个查询语句通常是通过一个聚合函数来返回一个单值
       2 --以下查询名为李军的学生所选课程数目
       3 select sno, sname,
       4 (
       5     select COUNT(*) from students 
       6     join scores on students.sno = scores.sno
       7     where students.sname = '李军'
       8     )as course_cnt
       9 from students
      10 where students.sname = '李军'
    • 派生表
       1 --派生表(内联视图)是将子查询作为一个表来处理,这个由子查询产生的新表就被称为“派生表”,类似于临时表
       2 --一下查询同时操作系统和计算机导论的学生
       3 select students.sno,students.sname
       4 from
       5 (
       6     select * from scores 

      7
      where scores.cno = (select cno from courses where courses.cname = '操作系统') 8 )as t1 9 join 10 ( 11 select * from scores 12 where scores.cno = (select cno from courses where courses.cname = '计算机导论') 13 )as t2 14 on t1.sno = t2.sno 15 join students on t1.sno = students.sno

      当然也可用以下查询实现

      1 select sno,sname from students where sno in (
      2 select sno from scores where cno = (select cno from courses where courses.cname = '计算机导论'))
      3 and sno in (
      4 select sno from scores where cno = (select cno from courses where courses.cname = '操作系统'))

       返回结果是相同的

    • 开窗函数
      一组行被称为一个窗口,开窗函数是指可以用于“分区”或“分组”计算的函数,这些函数结核OVER字句对组内的数据进行编号,并进行求和、计算平均值等统计。
      如SUM、AVG等函数
      • 将OVER字句与聚合函数结合使用
        • 1 --查询每门课的平均分,over作用:按课号分好组,然后求平均分
          2 select distinct courses.cno, cname,CAST( 1.0*AVG(degree)over(partition by scores.cno)as decimal(5,2)) as avg_degree
          3 from courses join scores on courses.cno = scores.cno 
          4 
          5 --大小为5,保留两位小数
          6 --as decimal(5,2)
          7 
          8 --cast(xxx as decimal)

      • 将OVER字句与排名函数一起使用 
        • 排名函数为分区中的每一行返回一个排名值,根据所用函数的不同,某些行可能与其他行具有相同的排名值,排名函数具有不确定性。
          • RANK()函数:相同的值会有相同排名
            1 --查询各学生的总分班级排名
            2 select *, chinese+math+english as total,
            3 RANK() over
            4 (partition by class order by chinese+math+english desc) as class_rank
            5 from scores
            6 order by chinese+math+english desc

          • DENSE_RANK():用法同RANK(),但排名的取值是连续的
            1 --DENSE_RANK查询各学生的总分班级排名
            2 select *, chinese+math+english as total,
            3 DENSE_RANK() over
            4 (partition by class order by chinese+math+english desc) as class_rank
            5 from scores
            6 order by chinese+math+english desc

            注意最后一个学生的名次,与RANK比较

          • NTILE():分组
            1 --NTILE:将学生按成绩划分到3个组中
            2 select *, chinese+math+english as total,
            3 NTILE(3) over
            4 (order by chinese+math+english desc) as ngroup
            5 from scores



            1 --NTILE:将学生以班级为单位按成绩划分到3个组中
            2 select *, chinese+math+english as total,
            3 NTILE(3) over
            4 (partition by class order by chinese+math+english desc) as ngroup
            5 from scores

          • ROW_NUMBER:返回结果集中每个分区内行的序列号
            1 select *, chinese+math+english as total,
            2 ROW_NUMBER() over
            3 (PARTITION BY class order by chinese+math+english desc) as ngroup
            4 from scores

    • 公用表表达式
      将查询语句产生的结果集指定一个临时命名的名字,这些命名的结果集就称为公用表表达式      

      1 --查询时显示学生所在班级人数
      2 with class_cnt(class, cnt) as 
      3 (
      4     select class,count(*) from scores
      5     group by class)
      6 select scores.*,class_cnt.cnt as class_cnt from scores
      7 join class_cnt on scores.class = class_cnt.class

  • 相关阅读:
    Java集合类: Set、List、Map、Queue使用场景梳理
    Java通过JDBC进行简单的增删改查(以MySQL为例)
    Servlet学习笔记
    Tomcat原理详解
    Tomcat的JVM和连接数设置
    Google Chrome 未响应。是否立即重新启动?---解决方法(秒速解决)
    LDAP服务器的概念和原理简单介绍
    Java IO流学习
    JavaScript_js模拟键盘输入
    Java_类似java.lang.VerifyError: Expecting a stackmap frame at branch target 22 in method的解决方法
  • 原文地址:https://www.cnblogs.com/2020R/p/13181502.html
Copyright © 2011-2022 走看看