230 likes | 464 Views
第 8 章 数据检索. 本章教学概要. 主要内容 8.1 SELECT 语句 8.2 使用 SELECT 语句进行简单查询 8.3 使用 T-SQL 语句进行高级查询 8.4 使用企业管理器进行查询 8.5 分布式查询简介 教学目标 掌握 SELECT 语句的基本语法 掌握简单的单表查询 掌握数据的高级查询操作. 8.1 SELECT 语句. 1.SELECT 语句的基本语法 2.SELECT 语句中各子句的说明
E N D
本章教学概要 主要内容 8.1 SELECT语句 8.2使用SELECT语句进行简单查询 8.3使用T-SQL语句进行高级查询 8.4使用企业管理器进行查询 8.5分布式查询简介 教学目标 掌握SELECT 语句的基本语法 掌握简单的单表查询 掌握数据的高级查询操作
8.1 SELECT 语句 • 1.SELECT 语句的基本语法 • 2.SELECT语句中各子句的说明 • ALL|DISTINCT|TOP n:ALL指定在结果集中可以包含重复行,ALL 是默认设置;关键字DISTINCT指定SELECT 语句的检索结果不包含重复的行; TOP n选项限定了要返回的行数。 • 选择列表:描述进入结果集的列,它是由逗号分隔的表达式的列表。但也可能是其它表达式,例如常量或 Transact-SQL 函数。如果select_list使用 *,表明指定返回源表中的所有列。 SELECT [ALL | DISTINCT][TOP n] <选择列表> [INTO <新表名>] [FROM] {<表资源>} [,…n] [WHERE] <搜索条件> [GROUP BY] {<分组表达式>}[,…n] [HAVING] <搜索条件> [ORDER BY] {<字段名[ASC|DESC]>} [,…n]
INTO 〈新表名〉:指定查询到的结果集存放到一个新表中。新表名为 • 指定新表的名称。 WHERE 子句指定限制查询的条件。 • 在搜索条件中,可以使用比较操作符、字符串、逻辑操作符来限制返回 • 的行数。 • GROUP BY子句是对结果集进行分组。 • HAVING 子句是在分组的时候,对字段或表达式指定搜索条, • HAVING 子句通常与 GROUP BY 子句一起使用。 • ORDER BY子句对结果集按某种条件进行排序。 • [ ASC | DESC ]:ASC和DESC关键字用于指定结果集是按升序还是按降序排序,DESC降序排序,ASC升序排序,默认为升序。 • 注意:① 必须按照正确的顺序指定 SELECT 语句中的子句。 ② 对数据库对象的每个引用必须具有唯一性。如果有多个数据库对象带有相同的名称。采用库名.表名的形式来引用;如果有相同的列名,则采用表名.字段名的形式来引用。
8.2 使用SELECT语句进行简单查询 • 最基本的SQL查询语句 • 格式:SELECT *|选择列表[,...n] FROM表名 • 功能:从指定表中查询所有信息或指定列的信息。 • 【例8-1】从student表中分别检索出学生的所有信息及学号、姓 • 名信息。 • USE jwgl • GO • SELECT * FROM student • SELECT student_id , student_name FROM student • 注意: 在SELECT后的列名的顺序决定了显示结果中的列序 在查找多列内容时,用‘,’将各字段分开
2. 改变列标题的显示 • 在缺省情况下,执行上面的SQL语句后,查询结果中显 • 示的列标题是列名。可以在SELECT语句中用‘列标题’= • 列名或‘列标题’AS 列名 来改变列标题的显示。 • 【例8-2】从student表中分别检索出学生的学号、姓名信息并分别加上“学生”、“学号”的标题信息。 USE jwgl GO SELECT '学号'=student_id , '姓名'=student_name FROM student SELECTstudent_id AS'学号', student_name AS '姓名' FROM student
3. 使用WHERE子句的查询 • 大部分查询都不是针对表中所有行的查询,而是从整个表中选出符合条件的信 • 息,要实现这样的查询就要用到WHERE子句。 • 1. WHERE子句的语法形式 • WHERE子句的语法形式如下: • SELECT 选择列表 • FROM 表资源 • WHERE 搜索条件 • 其中搜索条件: 比较: =、>、<、>=、<=、<> 范围:BETWEEN(在某个范围内) 、NOT BETWEEN(不在某个范围内) 列表:IN(在某个列表中)、NOT IN(不在某个列表中) 字符串匹配:LIKE(和指定字符串匹配)、NOT LIKE(和指定字符串不匹配) 空值判断:IS NULL(为空)、 IS NOT NULL(不为空) 组合条件:AND(与)、 OR(或) 取反:NOT • 注意:应该避免使用否定条件,查询优化器不能识别否定条件。
【例8-3】从student_course表中检索成绩小于60分的学生信息。【例8-3】从student_course表中检索成绩小于60分的学生信息。 • USEjwgl • GO • SELECT * FROM student_course WHERE grade<60 • 【例8-4】从student_course表中检索成绩介于60至80分之间的学生信息。 • USE jwgl • GO • SELECT * FROM student_course • WHEREgrade BETWEEN 60 AND 80 • 【例8-5】从student_course表中检索学号‘g9940202’,‘g9940204’,‘g9940206’ • 的学生信息。 • USE jwgl • GO • SELECT * FROM student_course • WHERE student_idIN ('g9940202','g9940204','g9940206')
【例8-6】从student表中分别检索出姓张的所有同学的资料;名字的第二个字是“红”或“虹”的所有同学的资料。【例8-6】从student表中分别检索出姓张的所有同学的资料;名字的第二个字是“红”或“虹”的所有同学的资料。 • USE jwgl • GO • SELECT* FROM student WHERE student_name LIKE '张%' • SELECT* FROM student WHEREstudent_name LIKE '_[红,虹]%' • 【例8-7】从student表中检索出家庭地址列为空值的同学的信息。 USE jwgl GO SELECT * FROM student WHERE home_addr IS NULL 其它示例
4. TOP和DISTINCT关键字 • 1. TOP 关键字:返回表中前n行或前一个百分数的数据。 • 【例8-8】分别从student表中检索出前5个及表中前面20%的学生的信息。 • USE jwgl • GO • SELECTtop 5 * FROM student • SELECTtop 20 PERCENT * FROM student • 2. DISTINCT关键字:消除重复行。 • 【例8-9】从student表中检索出所有姓名不重复的学生的信息。 • USE jwgl • GO • SELECT DISTINCTstudent_name FROM student
5. 使用ORDER BY子句对结果进行排序 • 前面介绍的数据检索所查询出来的数据都没有经过排序,这不利于 • 对数据结果的查看。通过ORDER BY子句,可以改变查询结果的显 • 示顺序。 • 在使用ORDER BY时,请注意以下几点: ① 如果没有指定是升序,还是降序,则缺省为升序。 ② 可以对多达16个列执行ORDER BY语句。 • 【例8-10】从student_course表中按成绩顺序检索出所有学生的信息。 USE jwgl GO SELECT* FROM student_course ORDER BY grade
6. 计算列的使用 • 查询数据时,经常需要对表中数据计算后才能得到满意的结果,SQL • Server在数据查询中提供了计算的能力。 • 【例8-11】从数据库northwind表products中检索出货品号(productid)、货品单价(unitprice)、货品库存量(unitsinstock)及货品的总价值。 USE northwind GO SELECT productid , unitprice, unitsinstock , unitprice * unitsinstock FROM products 7.基于多个检索条件的查询 • 在WHERE子句中,也可以使用逻辑运算符来连接多个条件,构成一 • 个复杂的条件进行查询。可以使用以下3种逻辑运算符:AND、OR、 • NOT。 • 【例8-12】从student_course表中检索出成绩大于等于80分、小于等于100分的学生的信息。 USE jwgl GO SELECT * FROM student_course WHERE (grade>=80 AND grade<=100 )
8.3 使用T-SQL语句进行高级查询 • 多表查询 • ⑴ 用于FROM子句连接: • SELECT 选择列表 • FROM {表名[连接类型] JOIN表名 ON连接条件} • WHERE 搜索条件 • 连接的类型有如下三种: 内连接(INNER JOIN),默认的连接方式是内连接。 • 交叉连接(CROSS JOIN) 外连接(OUTER JOIN) ⑵ 用于WHERE子句连接: SELECT 选择列表 FROM 表名 WHERE {表名.列名 连接操作符表名.列名}[…n] ON 搜索条件
【例8-13】从student及student_course两个表中检索学生的学号、姓名、学习课程号及课程成绩。【例8-13】从student及student_course两个表中检索学生的学号、姓名、学习课程号及课程成绩。 USE jwgl GO select student.student_id , student.student_name ,student_course.course_id , student_course.grade fromstudent , student_course WHERE student.student_id = student_course.student_id • 【例8-14】从student、course及student_course三个表中检索学生的学号、姓名、学习课程号、学习课程名及课程成绩。 USE jwgl GO SELECTstudent.student_id ,student.student_name ,student_course.course_id , course.course_name , student_course.grade from student , student_course , Course WHERE student.student_id = student_course.student_id AND course.course_id = student_course.course_id 思考:将【例8-13】和【例8-14】中分别 用另外一种形式写出其查询语
2. 使用UNION子句 • UNION子句的作用是把两个或多个SELECT语句查询的结果组合成一个 • 结果集。这里查询的多个表不要求有关联。 • 语法格式:Select语句 UNION [ALL] Select语句 […n] • 使用UNION时,请注意以下几点: ① UNION中从源表选择的所有列表必须具有相同列数、相似数据类型和相同的列序。 ②在合并结果时,将从结果集中删除重复行。若使用ALL,结果集中包含所有的行。 ③ 列名来自第一个SELECT语句。 • 【例8-15】用UNION子句将student表中学生的学号、姓名及teacher表中教师号、教师姓名组合在一个结果集中。 USE jwgl GO SELECT student_id , student_name FROM student UNION SELECT teacher_id , teacher_name FROM teacher
3. 使用GROUP BY子句 • 如果要在数据检索时对表中数据按照一定条件进行分组汇总或求平均值,就要在 • SELECT语句中与GROUP BY 子句一起使用集合函数。使用GROUP BY子句进 • 行数据检索可得到数据分类的汇总统计、平均值或其它统计信息。 • GROUP BY子句的语法形式: • SELECT字段名列表 FROM 表名 WHERE查询条件 [GROUP BY [ALL]分组表达式[…n] [HAVING分组筛选条件] • 注意: 如果GROUP BY子句使用ALL关键字,WHERE子句将不起作用。 HAVING子句排除不满足条件的组, HAVING子句是针对GROUP BY子句 的,没有GROUP BY子句时使用HAVING子句是没有意义的。 • 【例8-16】用GROUP BY句汇总出student_course表中学生的学号及总成绩。 USE jwgl GO SELECT '学号‘ = student_id , '总成绩‘ = sum(grade) FROM student_course GROUP BY student_id • 【例8-17】用GROUP BY句汇总出student_course表中总分大于450分的学生的学号及总成绩。 USE jwgl GO SELECT '学号‘ = student_id , '总成绩‘ = sum(grade) FROM student_course GROUP BY student_id HAVING sum(grade)>450
4. 使用COMPUTE和COMPUTE BY子句 • 使用GROUP子句对查询出来的数据做分类求和或求平均值,只能显示统计的 • 结果,看不到具体的数据。使用COMPUTE和COMPUTE BY就既能浏览数据 • 又看到统计的结果。语法形式如下: COMPUTE 表达式 (列名 ) […n] [BY 字段名列表 ] • 【例8-18】用COMPUTE子句汇总出student_course表中每个学生的学号及总 • 成绩。 USE jwgl GO SELECT '学号‘ = student_id , '成绩‘ = grade FROM student_course ORDER BY student_id COMPUTE SUM(grade) • COMPUTE类似于总计。如在COMPUTE后加上BY关键字,则查询结果为带 • 具体内容的分类统计。 • 【例8-19】用COMPUTE BY子句按学号汇总出student_course表中每个学生 • 的学号及总成绩。 USE jwgl GO SELECT ‘学号‘ = student_id , ’成绩‘ = grade FROM student_course ORDER BY student_id COMPUTE SUM(grade) BYstudent_id
注意:在使用COMPUTE和COMPUTE BY时,有如下限制: DISTINCT不允许同集合函数一起用,不能包含text、 ntext、image数据类型。 COMPUTE子句中的列必须在SELECT后面的选择列 表中。 SELECT INTO不与COMPUTE子句一起使用。 若使用了COMPUTE BY,则必须使用ORDER BY。 COMPUTE BY后出现的列必须与ORDER BY后出现 的列相同,或者是它的子集。它必须具有相同的从左到 右顺序并且以相同的表达式开头,不能跳过任何表达式。
5. 嵌套查询 • 如果先通过一个查询查出一个结果集,再在这个结果集中进行查询的话就 • 是嵌套查询。嵌套查询是用一条SELECT语句作为另一条SELECT语句的一 • 部分。外层的SELECT语句叫外部查询,内层的SELECT语句叫内部查询。 • 嵌套查询的执行流程是,首先执行内部查询,它查询出来的数据并不被显 • 示出来,而是传递给外层SELECT语句,作为该SELECT语句的查询条件使 • 用。子查询可以多层嵌套。 • 1.使用IN或NOT IN关键字 • 【例8-20】查询出“g99402”班所有男生的学号、课程号及相应的成绩。 • USE jwgl • GO • SELECT student_course.student_id , student_course.course_id , student_course.grade • FROM student_course • WHERE student_id IN • ( SELECT student_id FROM student • WHERE class_id = 'g99402' AND sex = 1 )
2. 使用EXSISTS 或NOT EXSISTS关键字 • EXISTS关键字和IN关键字不同:IN连接的是表中的列,而EXISTS连接的是表 • 和表,通常不需要特别指出列名,可以直接使用 *。由于EXISTS连接的是表, • 所以,子查询中必须加入表与表之间的连接条件。 • 【例8-21】使用EXSISTS关键字查询出“g99403”班学生的学号、课程号及相应 • 的成绩。 • USE jwgl • GO • SELECT student_course.student_id , student_course.course_id , student_course.grade • FROM student_course • WHERE EXISTS • ( SELECT * FROM student • WHERE student_course.student_id = student.student_id • AND student.class_id = 'g99403‘) • 3. 使用嵌套子查询的几点说明: 外部查询依赖于子查询的求值结果。 子查询必须被括在圆括号内。 以比较操作符引导的子查询的选择列表只能包括一个表达式或列名。否 则SQL Server会报错。
6. 在查询的基础上创建新表 • SELECT INTO的作用是,在查询的基础上创建新表。若建临时表,必须 • 在表前设置#(局部临时表)或# #(全局临时表)。新表的行和列是来自 • 查询结果,临时表是创建在tempdb数据库上。 • 【例8-22】创建#temp_grade的临时表,该临时表有两个列: • student_id,grade,要求学生的成绩grade大于95分。然后,再从临时表 • #temp_grade查询数据。 USE jwgl GO SELECT student_id , grade into #temp_grade FROM student_course WHERE grade>=95 USE tempdb GOSELECT * FROM #temp_grade
也可以用SELECT语句创建一个永久表。永久表是创建在基也可以用SELECT语句创建一个永久表。永久表是创建在基 • 表所在的数据库里。 • 【例8-23】创建grade_table的永久表,该临时表有两个列:student_id,grade.要求学生的成绩grade大于95分。 USE jwgl GO SELECT student_id , grade into grade_table FROM student_course WHERE grade>95 8.4 使用企业管理器进行查询 8.5 分布式查询简介 演示
本章教学小结 • 本章的重点在于SELECT语句应用,学好了 • SELECT 语句等于学好了数据库知识的一 • 半。在简要介绍了一些简单SELECT语句的 • 使用后,本章重点介绍了一些SELECT语句 • 的高级应用。