SQLServer数据库操作总结(sql语法的使用)(四)

2014-11-24 11:13:17 · 作者: · 浏览: 5
where t1 like '%30!%%'  escape '!'

3.2.9 NULL 空值查询


语法: 列名 IS [NOT] NULL 空值是未确定的值或其值尚不知道。

操作:查询还没有考试的学生的学号和相应的课程号
SELECT Sno, Cno FROM SC  WHERE Grade IS NULL

注意:空值不是一个确定的值,所以不可以用等于或不等于来比较或衡量

3.2.10 AND OR 多重条件查询


语法:当需要多个查询条件时,可以在WHERE子句中使用逻辑运算符AND和OR来组成多条件查询
操作:查询C002和C003课程中考试成绩在80~90的学生的学号、课程号和成绩
 SELECT Sno, Cno, Grade FROM SC  
    WHERE Cno IN( 'C002', 'C003') 
    AND Grade BETWEEN 80 AND 90

注意:OR的优先级小于AND,要改变运算的顺序可以通过加括号的方式实现
SELECT Sno, Cno, Grade FROM SC
    WHERE (Cno = 'C001' OR Cno = 'C002') 
      AND Grade BETWEEN 80 AND 90

3.2.11 ORDER BY 对查询结果排序


语法:ORDER BY <列名> [ASC | DESC ] [,<列名> … ]
说明:按<列名>进行升序(ASC)或降序(DESC)排序;当用多个列排序时,这些列在该子句中出现的顺序决定了对结果集进行排序的方式
操作:查询全体学生详细信息,结果按系名升序排列,同一个系的学生按出生日期降序排列
SELECT * FROM Student 
 ORDER BY Dept ASC, Birthdate DESC

3.2.12 使用聚合函数


语法:
COUNT(*):统计表中元组的个数。
COUNT([DISTINCT] <列名>):统计列值个数
SUM(<列名>):计算列值的和值(必须是数值型列)。
AVG(<列名>):计算列值的平均值(必须是数值型列)。
MAX(<列名>):得到列值的最大值。
MIN(<列名>):得到列值的最小值。
除COUNT(*)外,其他函数在计算过程中均忽略NULL值。

操作1:统计选修了课程(SC)的学生人数。
SELECT COUNT(DISTINCT Sno) FROM SC

操作2:计算学号为“0811101”的学生的考试总成绩

SELECT SUM(Grade) FROM SC     WHERE Sno = '0811101'

注意!:聚合函数不能出现在WHERE子句中。
操作:查询学分最高的课程名,如下写法是错误的!
SELECT Cname FROM Course WHERE Credit = MAX(Credit)
应该改为:
declare @credit int
select @credit=max(credit) from course
select cname from course where credit=@credit

3.2.13 GROUP BY 分组


语法: [GROUP BY <分组条件>]
作用:细化聚合函数的作用对象
操作1:统计每门课程的选课人数,列出课程号和选课人数。对查询结果按Cno的值分组,所有具有相同Cno值的元组为一组,然后再对每一组使用COUNT计算,求出每组的学生人数。
SELECT Cno, COUNT(Sno) FROM SC 
GROUP BY Cno

操作2:统计每个学生的选课门数和平均成绩。
SELECT Sno as 学号, COUNT(*) as 选课门数,   AVG(Grade) as 平均成绩 FROM SC 
GROUP BY Sno

注意: 1.GROUP BY子句中的分组依据列必须是表中存在的列名,不能使用AS子句指派的列别名。 2.带有GROUP BY 子句的SELECT语句的查询列表中只能出现分组依据列和统计函数,因为分组后每个组只返回一行结果。

操作3:带WHERE子句的分组。统计每个系的女生人数。
SELECT Dept, Count(*) 女生人数 FROM Student  
  WHERE Sex = '女' 
  GROUP BY Dept

操作4:按多个列分组。统计每个系的男生人数和女生人数,结果按系名的升序排序。
SELECT Dept, Sex, Count(*) 人数,  FROM Student 
  GROUP BY Dept, Sex
  ORDER BY Dept

3.2.14 HAVING 限制分组结果


语法:HAVING用于对分组自身进行限制,它有点象WHERE子句,但它用于组而不是对单个记录。
操作1: 查询选课门数超过3门的学生的学号和选课门数。
SELECT Sno, Count(*) 选课门数 FROM SC 
  GROUP BY Sno HAVING COUNT(*) > 3

处理过程:先执行GROUP BY子句对SC表数据按Sno进行分组,然后再用统计函数COUNT分别对每一组进行统计,最后筛选出统计结果满足大于3的组。分组的优先级大于查询,having是分组内操作。
操作2:查询选课门数大于等于4门的学生的平均成绩和选课门数
SELECT Sno, AVG(Grade) 平均成绩, COUNT(*) 选课门数
  FROM SC 
  GROUP BY Sno 
  HAVING COUNT(*) >= 4

3.2.15 小结


1.在分组操作之前应用的筛选条件,比在WHERE子句中指定更有效。
2.在HAVING子句中指定的筛选条件,应该是那些必须在执行分组操作之后应用的筛选条件。
3.将所有应该在分组之前进行的筛选条件放在WHERE子句中而不是HAVING子句中。

3.3 多表查询

多表连接查询分类三种:

1.内连接(INNER JOIN):
分为三种:等值连接、自连接、不等连接

2.外连接(OUTER JOIN):
分为三种:左外连接、右外连接、全外连接

3.交叉连接(CROSS JOIN) :
没有WHERE子句,它返回连接表中所有数据
行的笛卡尔积

3.3.1 内连接

语法:ANSI方式的连接格式

FROM 表1 [INNER] JOIN 表2 ON <连接条件>

连接条件语法格式:

[<表名1.>][<列名1>]<比较运算符>[<表名2.>][<列名2>]

内连接执行过程:

首先取表1中的第1个元组,然后从头开始扫描表2,逐一查找满足连接条件的元组,
找到后就将表1中的第1个元组与该元组拼接起来,形成结果表中的一个元组。
表2全部查找完毕后,再取表1中的第2个元组,然后再从头开始扫描表2, …
重复这个过程,直到表1中的全部元组都处理完毕为止。

操作1:查询学生的选课情况。学生信息在student表中,选课信息在sc表中。两张表都存放着学生的学学号sno。

SELECT * FROM Student 
INNER JOIN SC
ON Student.Sno=SC.Sno
操作2:去除重复列。如果不指定查询结果的列名(如操作1)则直接将两个表拼接在一起,学号列会重复。为了避免重复,需要制定列名。

SELECT Student.Sno, Sname, Sex, Sage, Dept, Cno, Grade FROM Student
JOIN SC ON Student.Sno = SC.Sno

操作3:指定列别名 ,参照前面说过的格式:<源表名> [ AS ] <表别名>
SELECT Sname, Cno, Grade 
  FROM Student S JOIN SC  
  ON S.Sno = SC.Sno
  WHERE Dept = '计算机系'
注意:当为表指定了别名时,在查询语句中的其他地方,所有用到