ACCP学习旅程之----- SQL Server(第五章 数据查询(二))

 特别注意:主外健关系中,名字可以不同,类型和长度必须相同。
1¥ 模糊查询
    模糊查询提取的数据不一定是确切的,查询者对查询条件也是模糊的、大概的、不特别明确的。
1$ 使用Like进行模糊查询
   Like运算符用于匹配字符串或字符串的一部分
   只能用于字符串,所以仅用于char或varchar数据类型
2$ 使用Between…And在某个范围内进行查询
  (使用not between来进行取反)--略
3$ 使用IN在列举内进行查询(用,分开列举值,使用not in来进行取反)
2¥ SQL Server中的聚合函数

特别注意:带有聚合函数(如:sum)的查询只能返回一行数据(数据中
          含有求和结果),故不能直接与可能返回多行的列一起查询。
如: select sum(ytd_sales),Price from titles where type=”business”
1.。Sum(返回表达式中以sum参数为列名的数据项的总和)
     只能用于数字类型数据的列,不能汇总字符、日期等其他字符。
   如:select sum(ytd_sales) from titles where type=’business
2.。Avg(返回表达式中以Avg参数为列名的数据项的平均值)
     只能用于数字类型数据的列,计算平均值时分母不含null行
   如: select avg(score) as 平均成绩 from score where score>60
3.。Max和Min(返回表达式中以Max或Min参数为列名的数据项中的
               最大值或最小值)
     可用于的数据类型:
             数字型      比较数值的大小
             字符型      西文按照ASCII码排序顺序比较
                         中文按照汉字拼音ASCII码排序顺序比较
           时间日期型    时间越早值越小,越晚值越大
4.。Count(返回表达式中以Count参数为列名的所有非空数据项的计数)
            如: 查询及格学生的人数
         select count(sname) from score where Score>60
特别注意:如果Count(*),即表示不指定列而计算表中的所有行的计数
          这种情况下,即使表中只有一行,且全部为空值null,也返回
          查到有1行数据
    如:select count(*) from score where score>60
3¥ 分组查询
1$ 使用Group By进行分组查询
标准形式:
    语法:   select <列名>
             from <表名>
             [where <查询条件表达式>]
             [order by <排序的列名> [ASC 或 DESC]]
             [group by <非聚合表达式的所有列>]
             [having <条件子句>]
功能:
1)指定用来放置输出行的组。
2)如果 SELECT 子句 <select list> 中包含聚合函数,则 GROUP BY
  将计算每组的汇总值。
3)指定 GROUP BY 时,选择列表中任意非聚合表达式内的所有列
   都应包含在 GROUP BY 列表中,或者 GROUP BY 表达式必须
   与选择列表表达式完全匹配。
如: 按照课程编号查询课程的平均成绩(课程编号不能重复)
     select CourseId, Avg(score) as 课程平均成绩
     from Score
     Group By CourseId
即:
    由于使用了Group By CourseId
    先在表中把相同的CourseId合为一组(决定了输出结果的行数)
    然后把同一组中的分数记录值用聚合函数处理得出单行结果,
    显然,由于输出结果中只有三行,如想显示所有学员编号不行了。
最终效果:
按照表中不同的CourseId分组,计算各个学生的平均成绩
特别注意:
即:使用Group By时,后面只能跟两种数据项
    被分组的列名
    为每个分组返回一个值的表达式,如以列名为参数的聚合函数
   (这种情况是指非要一一对应时)
如: select CourseId, Avg(score) as 课程平均成绩
     from Score
     Group By CourseId,Avg(score)
按照多列进行分组查询
如:
 select StudentID as 学员编号,CourseID as 内部测试,
                    Avg(score) as 内部测试平均成绩
  from Score
  Group By StudentID,CourseID
即:只要存在StudentID与CourseID的不同组合就分为一组,
    这样就决定了结果的输出行数
    这时可能出现同一StudentID多次考同一CourseID的情况
    因此,用聚合函数,合并相同的CourseID,得到一个单行的结
    果,如Avg(score)
2$ 使用Having子句进行分组后再筛选
  分组后的条件的筛选必须使用Having子句
  指定分组完成后的在此基础上再搜索的条件。
  也可以看成是在分好的组中,依据Having的要求,去掉不符合的组。
  HAVING 只能与  SELECT 语句一起使用。
  HAVING 通常在 GROUP BY 子句中使用。
 如果不使用 GROUP BY 子句,则 HAVING 的行
  为与 WHERE 子句一样。
  如:
  select StudentId 编号,CourseId 课号,Avg(Score)平均分
  from Score
  group by StrudentId,CourseId
  having Count(Score)>1
  按照学员编号,课程编号进行分组查询,
 (即只要有学员编号与课程编号的一种组合就计为一个分组),
  并计算学员平均分
  同时,统计出相同的学员编号和课程编号下,成绩出现过1次以上的学
  生和课程名称
 (即,参加过补考的学生)
  特别注意:如果正确理解了,这只是个小窍门
如果同一个查询语句中存在非聚合、聚合列一起查询,则必须
使用group by 语句才能执行。
而且,group by 后面必须跟定所有的非聚合列名。

另外:

1.    Distinct  查询出某个字段不重复的记录

变态学习distinct
2007-10-31 17:18
select 中的DISTINCT用法
在 使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用 它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了 很久,用distinct不能解决的话,我只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。所以我花了很多时 间来研究这个问题,网上也查不到解决方案,期间把容容拉来帮忙,结果是我们两人都郁闷了。。。。。。。。。
下面先来看看例子:
      table
    id name
    1 a
    2 b
    3 c
    4 c
    5 b
库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。
比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。
select distinct name from table
得到的结果是:
    name
    a
    b
    c
好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:
select distinct name, id from table
结果会是:
    id name
    1 a
    2 b
    3 c
    4 c
    5 b
distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。
我们再改改查询语句:
select id, distinct name from table
很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。。。。。。。
很麻烦吧?确实,费尽心思都没能解决这个问题。没办法,继续找人问。
拉住公司里一JAVA程序员,他给我演示了oracle里使用distinct之后,也没找到mysql里的解决方案,最后下班之前他建议我试试group by。
试了半天,也不行,最后在mysql手册里找到一个用法,用group_concat(distinct name)配合group by name实现了我所需要的功能,兴奋,天佑我也,赶快试试。
报错。。。。。。。。。。。。郁闷。。。。。。。连mysql手册也跟我过不去,先给了我希望,然后又把我推向失望,好狠哪。。。。
欢迎光临学网,收藏本篇文章 [1] [2]
$False$
再仔细一查,group_concat函数是4.1支持,晕,我4.0的。没办法,升级,升完级一试,成功。。。。。。
终于搞定了,不过这样一来,又必须要求客户也升级了。
突然灵机一闪,既然可以使用group_concat函数,那其它函数能行吗?
赶紧用count函数一试,成功,我。。。。。。。想哭啊,费了这么多工夫。。。。。。。。原来就这么简单。。。。。。
现在将完整语句放出:
select *, count(distinct name) from table group by name
结果:
    id name count(distinct name)
    1 a 1
    2 b 1
    3 c 1
最后一项是多余的,不用管就行了,目的达到。。。。。
唉,原来mysql这么笨,轻轻一下就把他骗过去了,郁闷也就我吧(对了,还有容容那家伙),现在拿出来希望大家不要被这问题折腾。
哦,对,再顺便说一句,group by 必须放在 order by 和 limit之前,不然会报错,差不多了,发给容容放网站上去,我继续忙碌。。。。。。
2.
4¥ 多表连接查询

1$ 内连接查询(两表平行或平等连接)

   即要在同一个查询语句中,查出两个或多个平行连接表中的,列值。

   根据表中共同的列来进行匹配,特别是两表存在主外键关系时使用。
   通常会使用“=”或“<>”来比较两列数据是否相等

   关键字:[inner] join
1.。在Where子句中指定内连接条件

 如:查询学员姓名和成绩
    select sname, courseid, score
    from students [简称],score [简称]
    where student.scode=score.studentid
说明:sname,scode 来自于students表
      courseid,score 来自于score表
      两表按照student.scode=score.studentid连接
此种制定内连接的方法,是在from语句后面紧跟两个表名(可指定别名),然后用where语句指定连接条件。
2.。在From子句中使用Join…On来制定内连接条件
如:select sname,courseid,score
    from students as s inner join score as c
    on s.scode=c.studentid
特别注意:
    Sql中,执行Inner Join连接的速度跟“在Where子句中指定连接条件”的查询速度是不一样的。
3.。三表平行连接

  用where:
    select s.sname, cs.coursename, c.score
    from student s,course cs,c.score
    where cs.courseid=c.courseid and s.scode=c.studentid
  用inner join
    select s.name,cs.coursename,c.score
    from student s inner join score c on s.scode=c.studentid
                 inner join course cs on cs.courseid=c.courseid
   2$ 外连接查询(以两表中的某一个表为主进行匹配连接后查询)
   在外部连接中参与连接的表有主从之分
   以主表的每行数据去匹配从表的数据行,符合连接条件的数据将返回
   到结果集中
   不符合连接条件的行,将被填上null值后再返回到结果集中。
   关键字:left [outer] join  或 right [outer] join

   如: select sname,courseid,score
        from student as s left [outer] join score as c
        on s.scode=c.student
   说明:以student表为主,先保证该表中的scode数据行全部显示
         然后按照on后面的条件进行匹配,
         如果在score表中没有相应的数据,用null来填充。
特别注意:如果查询语句中的列名与关键字重名,如列名为name
          则加中括号即可。即[name]
另外:
1.。having子句大多数情况下后面都跟随查询中的聚合函数项
2.。Null和空格在查询中是不同的值
3.。所有内连接的问题都可以通过子查询的方法解决完成
 

你可能感兴趣的:(字符串,数据,查询,between,Accp)