SQL 查询语句

做~自己de王妃 提交于 2020-12-30 11:37:53

4.2 单表查询

  4.2.1 列名(表名)的别名(as 可以不加)

     给列名取别名既可以加 as 也可以不加。 (2008 - Sage、lower(Sdept)等可计算但无列名,需要指定列名)

     原列名既可以作为判断条件,也可以排序;列名的别名只能用作排序,不能用作判断条件。

     表名也可以有别名,给表名取别名既可以加 as 也可以不加;用表名或者表名的别名来引用列名,既可以排序也可以用作判断条件。(用表名或者表名的别名来引用列名的别名,既不可以排序也不可以作为判断条件)

  4.2.2 消除重复行 distinct

      select distinct Sno from SC

     消除取值重复的行,关键字是 distinct(默认缺损值是 ALL),这个是针对某一行而不是某一个字段。(也就是说只有当各行之间的每一个字段都完全相同才算是重复的)

  4.2.3 比较运算符、not 运算符

      select distinct Sno from SC where not grade < 60

     比较运算符: > 、>= 、< 、<= 、= 、!= 、<> 、!> 、!<

     not 运算符:针对的是某一个逻辑表达式(bool 表达式),而不是针对一个符号(比如 grade not < 60)。

          所以,运算符 not 可以与比较运算符同用,对条件求非,比如 not grade < 60

  4.2.4 确定取值范围 between…and…

      select Sname,Sage from student where sage not between 22 and 20        --这样是查不到的

     确定取值范围: between … and…、 not between … and…

     注意: between  A  and  B  相当于  >= A and <= B,顺序不能错。

  4.2.5 确定集合 in、not in

      select Sname,Sage,sdept from student where sdept in ('CS','ma')

     注意:要加括号的。

  4.2.6 模糊查询 like

      select *from student where sno= '95001'
      select *from student where sno like '95001'
      select *from student where sname like '刘%'
      select *from student where sname like '刘_'
      select *from student where sno like '9500_'
      select *from student where sname like '_呈%'
      select *from student where sname not like '刘%'

      select *from course where cname like 'DB\_M' escape '\'
      select *from course where cname like 'MA\%S' escape '\'
      select *from course where cname like 'MA%K__'

     字符匹配: [not] like % _ escept

     当 like 后面的字符串没有包含通配符的时候,like 就是 = 。

     _ :代表一个字符.默认每一个字符(数值,字母,汉字)采用ascii进行编码的.但是不管用什么方式进行编码,_代表的是一个字符,而不是一个字节

     escape 定义某一个字符,这个字符后面紧跟的通配符是不起通配作用的,当 like 比较的时候会忽略字符串中的 escape 定义某一个字符,而把其后的通配符当成一个普通的字符。

  4.2.7 涉及空值 null 的查询

      select *from student where sname = ''
      select *from student where ssex is null
      select *from student where sname is not null

     涉及空值的查询:is not null 。

     当是空值的时候只能用IS来判断,其他的都不可以。

     null表示什么都没有,而''表示的是长度为零的字符串。(null与任何类型的值进行算术运算的结果都为null )

  4.2.8 多重条件查询 and、or

     and 的优先级比or高,但是()可以改变优先级别

  4.2.9 对查询结果进行排序

      select * from SC where cno= '3' order by grade desc
      select * from SC order by sno,grade

     排序order by asc/desc (asc 是升序,是默认的缺损值,desc是降序的)

     order by a,b,c,d 像这种按照多个字段进行的排序,先按照第一个字段排序,再按照第二个字段排序,以此类推,但是第二个字段的排序是在第一个的基础上进行的,它不会去打乱第一个排序的,

   第一个排序其实就已经分成组了,第二个排序是在第一个排序的各个小组里面进行的排序。

  4.2.10 聚集函数(count、avg、sum、max、min)

      select * from student
      select count(*)from student      --不能加 distinct 或者 all
      select count(all sno) num from student
      select count(distinct sno) num from student

      select avg(distinct sage)from student      --必须是数字,非null值的加和除以非null值的个数
      select sum(distinct sage)from student      --必须是数字,非null值的加和
      select max(distinct sno)from student       --只要是可以比较大小的就可以,如果该列全是null,那么结果也是null
      select min(distinct sno)from student       --只要是可以比较大小的就可以,如果该列全是null,那么结果也是null

     对于这些集函数,dinstinct表示消除了重复的行,而默认缺损为all

  4.2.11 分组查询 group by

      select * from sc
      select cno from sc group by cno        --以某一列分组并筛选某一列就可以查看到该列所具有的不同的值

      --分组之后,每一组只会有一行,并且一组中只取一个值,所以如果要在查询结果中加入其他的列,要保证这些列在一组中只有一个值。
      select cno,sno from sc group by cno,sno           --分组是不会排序的
      select cno,sno from sc group by cno,sno order by cno

      select cno,count(sno)from sc group by cno
      select sno,count(cno) cnoNum     --选3门课以上的学生的选课数
        from sc group by sno 
        having count(distinct cno) >= 3
      select cno,count(sno)
        from sc
        where cno > 1 group by cno,sno         having count(sno)>0 order by cno

     上面的 sql 语句执行的顺序是:先分组,然后查询计算,然后在查询的结果中判断 where 和 having 条件,最后排序。

     分组与不分组的区别是:

        不分组的时候,(如果是多表的话,先要去连接)先查询,然后在查询结果中按照where子句的条件来筛选。

        而分组的时候,(如果是多表的话,先要去连接)是先分组,然后再执行查询,然后在查询结果中按照where子句和having子句的条件来筛选。

      Having后面的聚集函数是对每一最小组(按照 group by 后面的所有列进行的分组,是所有列而非某一列分组)的那些行进行运算的。

        另外,having 后面也可以对某列进行非聚集函数的条件判断,这种判断也是针对每一最小组的那些行。

    select top 10 a.sno,count(distinct cno) cno_num 
    from student as a,sc as b
    where a.sno = b.sno and a.sno ='95001' 
    group by a.sno
    having count(distinct cno)>= 2
    order by a.sno

    查询的执行步骤:

      先连接,然后按照条件去分组,然后按照组查询,先查询第一组(第一行),然后用where子句和having子句的条件来筛选,满足条件就保留,否则就舍去,然后查询第二行......,最后在查询出的结果中排序,然后在排好序的结果中去求top n。

  小结:

    1、分组是按照某个列来进行分组的,最后在该列中列值相同的就是一组了group by a,b,c先按照a进行分组,在按照a分好的每一组里面,再按照b进行分组,即保留了最开始的组,然后在按照b分好的组里面再按照c进行分组,以此类推......

    2、分组是不会排序的,排序和分组是两个独立的过程,排序是在分组查询之后,在最终的满足各种条件的查询结果里面来排序.

    3、如果在分组的时候要查询某些字段,那么一定要保证在最小组中的该字段是绝对唯一的,因为每一个最小组最后只会有一行记录有时候,用户知道是绝对的唯一的,但是计算机不知道,所以在这种情况下必要的时候

  可以再按照该字段进行一次分组,或者使用聚集函数。在使用集函数进行运算的时候,是对最小的组进行计算.

    4、没有分组的时候判断条件用where,分组之后对于某一组的聚集函数结果的判断条件是having,一般用于聚集函数count分组后对于某一个字段的判断还是用where

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!