第4章 查询数据和修改数据
学习目标 掌握SELECT语句结构; 掌握数据的基本查询方法; 掌握聚合函数、子查询的使用方法; 掌握使用Insert、Update、Delete管理数据。
学习重点 SELECT语句结构; 聚合函数、子查询的使用方法; 使用Insert、Update、Delete处理数据。
4.1 SELECT语句 SELECT 语句的语法格式如下: SELECT select_list [ INTO new_table ] FROM table_source [ WHERE search_condition ] [ GROUP BY group_by_expression ] [ HAVING search_condition ] [ ORDER BY order_expression [ ASC | DESC ] ]
4.2数据的基本查询 SELECT子句的语法格式如下: SELECT [ ALL | DISTINCT ][ TOP n [ PERCENT ] [ WITH TIES ] ] *| column_name | expression[ [ AS ] column_alias ]
4.2.1 SELECT子句 例4.1 显示stu表的所有记录。 USE students GO SELECT * FROM Stu
4.2.1 SELECT子句 例4.2 查找所有学生的学号,姓名及班级。 USE Students GO SELECT Stuid,Stuname,Class FROM Stu
4.2.1 SELECT子句 给字段命别名的方式有两种: 1、旧名 AS 新名 2、新名 = 旧名 例4.3 从Stu中显示出全部同学的电话号码。 USE Students GO SELECT Stuname As 姓名, phone As 电话号码 FROM Stu
4.2.1 SELECT子句 DISTINCT 关键字可从 SELECT 语句的结果中除去重复的行。 例4.4 从Stu表中显示系代号,并去掉重复记录。 USE Students GO SELECT DISTINCT Depid As 系代号 FROM Stu
4.2.1 SELECT子句 TOP 关键字限制返回到结果集中的记录的行数。 其语法格式为: TOP n [PERCENT] [ WITH TIES ] n 指定返回的行数。 如果指定了 PERCENT,则返回的是符合查询条件的记录的n%。
4.2.1 SELECT子句 例4.5 从Stu表中显示前5条学生记录。 USE Students GO SELECT TOP 5 * FROM Stu
4.2.1 SELECT子句 例4.6 从Stu表中显示80%的学生记录。 USE Students GO SELECT TOP 80 PERCENT * FROM Stu
4.2.2 WHERE 子句 1.用关系运算符
4.2.2 WHERE 子句 例4.7 从表Stu中找出所有的男生的电话号码。 USE Students GO SELECT Stuname As 姓名,Phone As 电话号码 FROM Stu WHERE Sex='男'
4.2.2 WHERE 子句 2.使用逻辑运算符 可以使用AND、OR、NOT等逻辑运算符来连接表达式,其返回值为布尔类型:TRUN或FALES。 AND表示两个条件都必须满足,其值为TRUN; OR表示任意满足其中的一个条件,其值为TRUN; NOT表示否定后面的表达式,其值取反。 当混合使用逻辑运算符时,NOT的优先级大于AND和OR。
4.2.2 WHERE 子句 例4.8 查询系代号为“1001”的女同学的信息。 USE Students GO SELECT StuID,StuName,Sex,Phone FROM Stu WHERE DepID=’1001’AND Sex=’女’
4.2.2 WHERE 子句 例4.9 查询系代号为”1001”或”1003”的同学的信息. USE Students GO SELECT * FROM Stu WHERE DepID=’1001’ OR DepID=’1003’
4.2.2 WHERE 子句 3.使用IN关键字 IN 关键字选择与列表中的任意一个值匹配的行。 test_expression [ NOT ] IN expression [ ,...n ] 值列表中的各个值之间是“或”的关系,只需等于其中的一个值即符合条件。
4.2.2 WHERE 子句 例4.10 找出系代号为“1001”、“1002”、“1005”的学生的姓名、电话号码和系代码。 例4.10 找出系代号为“1001”、“1002”、“1005”的学生的姓名、电话号码和系代码。 USE Students GO SELECT Stuname As 姓名, phone As 电话号码 ,Depid As 系代号 FROM Stu WHERE Depid IN(‘1001’,’1002’,’1005’)
4.2.2 WHERE 子句 4.使用BETWEEN关键字 使用BETWEEN关键字可以对指定范围进行搜索,返回介于两个指定值之间的值。 test_expr [NOT] BETWEEN begin_expr AND end_expr 其中test_expr、begin_expr 、end_expr的数据类型需相同。begin_expr 的值小于end_expr的值。
4.2.2 WHERE 子句 当不使用NOT时,等价于 当使用NOT时,等价于 test_expr>= begin_expr AND test_expr<=end_expr 当使用NOT时,等价于 test_expr<begin_expr OR test_expr> end_expr
4.2.2 WHERE 子句 例4.11 从成绩表Score表中选择分数在80-90分的同学的学号,课程代码和分数。 USE Students GO SELECT Stuid As 学号, Couid As 课程代码,Score As 分数 FROM Score WHERE Score Between 80 And 90
4.2.2 WHERE 子句 5.模糊匹配查询 使用LIKE 运算符,可用通配符代替搜索字符串中的一个或多个字符。 match_expression [ NOT ] LIKE pattern
4.2.2 WHERE 子句 要搜索的字符串可包含四种通配符(如表4-2)的任意组合。
4.2.2 WHERE 子句 例4.12 查找班级名称中包含“软件技术”四个字的同学信息。 USE Students GO SELECT * FROM Stu WHERE Class LIKE '%软件技术%'
4.2.2 WHERE 子句 6.查询空值 使用IS NULL可以查询字段中为空值的记录。 expression IS [ NOT ] NULL 例4.13 查询“电话号码”字段为空值的学生的学号和姓名。 USE Students GO SELECT StuID,StuName FROM Stu WHERE Phone IS NULL
4.2.3 ORDER BY子句 使用ORDER BY子句可以进行排序处理。 ORDER BY order_expression [ ASC | DESC ] ORDER BY 子句对查询结果中的一列或多列进行排序,排序可以按照升序进行(ASC),也可以按照降序进行(DESC)。如果没有指定升序还是降序,默认为 ASC。
4.2.3 ORDER BY子句 例4.14 查询课程代码为“A002”的所有成绩,按降序排列。 USE Students GO SELECT * FROM Score WHERE CouID='A002' ORDER BY Score DESC
4.2.3 ORDER BY子句 例4.15 查询“A002”课程分数最高的4位同学的学号和成绩,若后面行中出现分数相同的情况则保留。 USE Students GO SELECT TOP 4 WITH TIES StuID,Score FROM Score WHERE CouID='A002' ORDER BY Score DESC
4.2.3 ORDER BY子句 为了防止后面记录中出现排序字段值相等,但限于TOP语句规定显示记录条数无法显示,可以在TOP n后使用WITH TIES选项,保留后面记录中值相等的记录。
4.2.4 GROUP BY子句 聚合函数是在查询结果集中生成汇总值。
4.2.4 GROUP BY子句 例4.16 查询成绩表Scores中代码为“A001”的课程的平均成绩。 USE Students GO SELECT AVG(Score) As 平均成绩 FROM Scores WHERE CouID='A001'
4.2.4 GROUP BY子句 GROUP BY根据指定的字段值进行分组,如果 SELECT 子句的选择列表中包含聚合函数,则计算每组的汇总值。 GROUP BY语法格式如下: GROUP BY group_by_expression [ ,...n ] 注意: text、ntext 和 image 类型的列不能用于 group_by_expression。
4.2.4 GROUP BY子句 例4.17 查询成绩表Scores中每门课程的平均成绩。 USE Students GO SELECT CouID As 课程代码, AVG(Score) As 平均成绩 FROM Scores GROUP BY CouID
4.2.4 GROUP BY子句 注意: 指定 GROUP BY 时,SELECT列表中任一非聚合表达式内的所有列都应包含在 GROUP BY 列表中,或者 GROUP BY 表达式必须与SELECT列表中的表达式完全匹配。
4.2.4 GROUP BY子句 例4.18 查询每门课程已经学习的人数。 USE Students GO SELECT CouID,COUNT(*) FROM Scores GROUP BY CouID
4.2.5 HAVING子句 在使用了GROUP BY子句之后,才可以使用HAVING子句。 HAVING子句是对查询进行条件限制,和WHERE子句的区别在于: HAVING子句是对分组之后进行条件限制 WHERE子句主要对分组之前进行条件限制。
4.2.5 HAVING子句 例4.19 查询课程平均分大于80分的课程编号。 USE Students GO SELECT CouID,AVG(Score) FROM Scores GROUP BY CouID HAVING AVG(Score)>80
4.2.5 HAVING子句 例4.20学校要评三好学生,要求第一学期的单科成绩不低于70分,平均成绩不低于80分的同学方有资格参加评选,查询有资格参加三好生评选的学生的学号,并按平均成绩由高到低排序。 USE Students GO SELECT StuID,AVG(Score) FROM Scores WHERE Term =1 GROUP BY StuID HAVING AVG(Score)>=80 and min(score)>=70 ORDER BY AVG(Score) DESC
4.2.6 数据汇总 在查询中需要对某些数据进行汇总,可以使用前面所讲的GROUP BY语句和聚合函数外,还可以使用一种额外汇总数据的语句COMPUTE和COMPUTE BY子句。 其语法为: COMPUTE { { AVG | COUNT | MAX | MIN | SUM }( expression ) } [ ,...n ][ BY expression [ ,...n ] 使用COMPUTE子句可以在查询的结果集之外产生一个汇总,其中使用聚合函数进行。
4.2.6 数据汇总 例4.21 查询课程号为“A002”的成绩记录,并求该门课程的平均分。 USE Students GO SELECT * FROM Scores WHERE CouID=‘A002’ COMPUTE AVG(Score)
4.2.6 数据汇总 例4.22 查询每位学生的成绩的详细信息,并求其总分,平均分。 USE Students GO SELECT * FROM Scores ORDER BY StuID COMPUTE SUM(Score),AVG(Score) BY StuID
4.2.7 INTO子句 INTO子句的作用是将查询的结果存放到新的表中,类似于WINDOWS操作中常见的“另存为”。 注意:这个新的表不需要创建,直接由查询得出的字段及数据类型,记录所组成。 例4.23 将学生的学号,姓名,所在班级放入表S1中。 USE Students GO SELECT Stu,StuName,Class INTO S1 FROM Stu
4.3.多表联接查询 SQL Server 2000 中表的联接,可以分为三种类型。 .内联接 .外联接 *左外联接 *右外联接 *全外联接 .交叉联接
4.3.1内联接 内联接根据各个表之间的逻辑关系从两个或多个表中检索数据。 内联接的语法格式如下: FROM table_name INNER JOIN table_name ON join_conditions
4.3.1内联接 例4.24 查看学习课程代码为‘C001’课程的学生的学号,姓名,班级及该门课程的成绩。 USE Students GO SELECT Stu.stuid,stuname,class,score FROM Scores INNER JOIN Stu ON Scores.StuID=Stu.StuID WHERE CouID=’C001’
4.3.1内联接 在查询所引用的两个或多个表之间,任何重复的列名都必须用表名限定。 如果某个列名在查询用到的两个或多个表中不重复,则对这一列的引用不必用表名限定。 为表设定了别名后,要使用该表限定字段时,必须使用别名。
4.3.1内联接 例4.25 查询学号尾数为2,4,7的同学的学号,姓名,及各门课程的成绩。 UES Students GO SELECT S. StuID,S.StuName,C.CouName,C.Score FROM Stu AS S INNER JOIN Score AS O ON S.StuID=O.StuID INNER JOIN Course AS C ON O.CouID=C.CouID WHERE S.StuID LIKE ‘%[2,4,7]’
4.3.1内联接 内联接中还有一种特殊的联接:自联接。所谓自联接,就是表与表本身自己进行内连接。 例4.26 查询姓名相同的学生的信息。 USE Students GO SELECT A.StuID,A.StuName FROM Stu AS A INNER JOIN Stu AS B ON A.StuName=B.StuName WHERE A.StuID<>B.StuID
4.3.2外联接 外联接分为左外联接、右外联接或全外联接。 1.左外联接 : FROM table_name LEFT [OUTER]JOIN table_name ON join_conditions。 2.右外联接 : FROM table_name RIGHT [OUTER] JOIN table_name ON join_conditions。 3.全外联接 : FROM table_name FULL [OUTER]JOIN table_name ON join_conditions。
4.3.2外联接 例4.27 查询新开课程(没有学生学过的课程)。 USE Students GO SELECT C.CouID,C.CouName FROM Scores AS S RIGHT JOIN Course AS C ON S.CouID=C.CouID WHERE S.CouID IS NULL
4.3.2外联接 例4.28 查询每门课程有多少学生曾经学习过,若有新开课程,则显示0。 USE Students GO SELECT C.CouID,C.CouName,COUNT(S.StuID) FROM Course AS C LEFT JOIN Score AS S ON S.CouID=C.CouID GROUP BY C.CouID,C.CouName
4.3.3交叉联接 交叉联接将左表中的每一行与右表中的所有行联接,无联接条件。因此,交叉联接在实际中很少使用。
4.3.4 联合UNION UNION运算符将两个或多个 SELECT 语句的结果组合成一个结果集。 Select_statement UNION [ALL] Select_statement
4.3.4 联合UNION 注意: 在使用 UNION 运算符组合的语句中,所有选择列表的表达式数目必须相同(列名、算术表达式、聚合函数等)。 在使用 UNION 组合的结果集中的相应列、或个别查询中使用的任意列的子集必须具有相同数据类型,并且两种数据类型之间必须存在可能的隐性数据转换,或提供了显式转换。
4.4子查询 子查询是一个 SELECT 查询,且嵌套在 SELECT、INSERT、UPDATE、DELETE 语句或其它子查询中。 任何允许使用表达式的地方都可以使用子查询。 子查询也称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。
4.4子查询 子查询的 SELECT 查询总是使用圆括号括起来。且不能包括 COMPUTE 或 COMPUTE BY 子句,如果同时指定 TOP 子句,则只能包括 ORDER BY 子句。 子查询可以嵌套在SELECT、INSERT、UPDATE 或 DELETE 语句内,或者其它子查询中。最多可嵌套到 32 层。
4.4.1子查询作表达式 若子查询返回的是单个值,则在任何可以使用表达式的地方都可以使用子查询。 例4.29 查询比A001课程最低分还低的学生的成绩。 USE Students GO SELECT StuID,Score FROM Scores WHERE Score<(SELECT MIN(Score) FROM Scores WHERE CouID=’A001’)
4.4.1子查询作表达式 例4.30 查询学生20070102的基本信息及平均成绩。 USE Students GO SELECT StuID,StuName,Sex,Phone, (SELECT AVG(Score)FROM Scores WHERE StuID=20070102) AS 平均分 FROM Stu WHERE StuID=20070102
4.4.1子查询作表达式 若返回的不是单个的标量值,而是多个值,则可以使用IN关键字。通过前面的学习已经知道可以通过 IN(或 NOT IN)与一列值或更多值进行匹配。 例4.31 查询电子信息系同学的电话号码。 USE Students GO SELECT Stuname As 姓名,phone As 电话号码 FROM Stu WHERE Depid IN (SELECT Depid FROM Dep WHERE Depname='电子信息系')
4.4.1子查询作表达式 子查询可由一个比较运算符(=、< >、>、> =、<、!>, ! < 或 < =)引入。 例4.32 查询何东同学所在系的系主任和他的电话号码。 USE Students GO SELECT director As 系主任,phone As 电话号码 FROM Dep WHERE Depid =(SELECT Depid FROM Stu WHERE Stuname='何东')
4.4.1子查询作表达式 若自查询返回的不是单个值,而是多个值,则可在子查询前加关键字ANY或ALL。 WHERE expression comparison_operator [ANY | ALL] (subquery) ANY表示只要其中一组比较符合条件即可;ALL表示每一组比较都要符合条件。
4.4.1子查询作表达式 例4.33 查询比A001课程的最低分还高的学生的成绩。 分析:若比A001课程的任意一个分数高,就比A001课程的最低分高。 USE Students GO SELECT StuID,Score FROM Scores WHERE Score>ANY(SELECT Score FROM Scores WHERE CouID=’A001’)
4.4.1子查询作表达式 例4.34 查询比A001课程的最高分还高的学生的成绩。 分析:必须比A001课程的每一个分数都高,才能比A001课程的最高分高。 USE Students GO SELECT StuID,Score FROM Score WHERE Score>ALL(SELECT Score FROM Score WHERE CouID=’A001’)
4.4.2 子查询作派生表 将子查询的结果作为一个派生表,替代外查询中所用的表。 例4.35 查询平均分在75分以上的学生的学号,姓名,平均分。 USE Students GO SELECT T.Stuid,T.StuName,AVG(Score) FROM Scores AS S INNER JOIN (SELECT Stuid,StuName FROM Stu) AS T ON S.StuID=T.StuID GROUP BY S.StuID HAVING AVG(Score)>75
4.4.3 相关子查询 可以用关联数据,执行一个相关子查询。 相关子查询中子查询需要执行多次,它的执行方式是: 外部查询将列值传递给内部查询;内部查询经过查询后,将值返回给外部查询;外部查询执行下一行数据,并重复上述过程。
4.4.3 相关子查询 例4.36 查询高于本门课程平均分的学生成绩。 USE Students GO SELECT S1.StuID , S1.Score FROM Scores AS S1 WHERE Score>(SELECT AVG(Score) FROM Scores AS S2 WHERE S1.CouID=S2.CouID )
4.4.3 相关子查询 例4.37 查询已经学完2门课程以上的同学的信息。 USE Students GO SELECT S.StuID,S.StuName FROM Stu AS S WHERE 2<(SELECT COUNT(*) FROM Scores AS C WHERE S.StuID=C.StuID)
4.4.4 使用EXISTS的子查询 使用 EXISTS 关键字引入一个子查询时,就相当于进行一次存在测试。 外部查询的 WHERE 子句测试子查询返回的行是否存在。 子查询实际上不产生任何数据;它只返回 TRUE 或 FALSE 值。
4.4.4 使用EXISTS的子查询 使用 EXISTS 引入的子查询语法如下: WHERE[NOT]EXISTS(subquery)
4.4.4 使用EXISTS的子查询 例4.38从Stu表中查询电子信息系的学生的姓名和电话号码。 USE Students GO SELECT Stuname As 姓名,phone As 电话号码 FROM Stu WHERE EXISTS (SELECT * FROM Dep WHERE Stu.Depid=Dep.Depid and Depname='电子信息系')
4.5数据的插入、修改及删除 4.5.1 数据的插入 INSERT 语句在简单的情况下有如下形式: INSERT [INTO] table_or_view [(column_list)] VALUES data_values
4.5.1 数据的插入 使用INSERT语句插入数据可采用下面两种方法进行: 用 VALUES 子句为一行指定数据值; 用 SELECT 子查询为一行或多行指定数据值。
4.5.1 数据的插入 1. 使用 INSERT...VALUES 插入行
4.5.1 数据的插入 例4.39 向表Dep插入一条新记录。 USE Students GO INSERT Dep VALUES (1006,'计算机系','张三','02854126871') --添加一条新记录 SELECT * FROM Dep --查看数据
4.5.1 数据的插入 例4.40 在课程表Course中插入一条新记录。 USE Students GO INSERT INTO Course(Couid,Couname) VALUES (1008,'SQL Server 2000基础') SELECT * FROM Course
4.5.1 数据的插入 2.使用 INSERT...SELECT 插入行
4.5.1 数据的插入 例4.41新建立一张数据表Stu1,从Scores表中选择学号为“20070102”的同学的信息将其添加到新数据表Stu1中。 (1)建立数据表Stu1 USE Students GO CREATE TABLE Stu1( Stuid int not null, Sex char(1) null)
4.5.1 数据的插入 (2)使用INSERT添加语句 INSERT INTO Stu1 SELECT Stuid,Sex From Stu WHERE Stuid='20070102' (3)使用SELECT查询结果 SELECT * FROM Stu1
4.5.1 数据的插入 此例也可以使用 SELECT INTO完成。 分析:使用SELECT INTO子句时,不必手动创建数据表Stu1,直接使用查询语句完成。 USE Students GO SELECT Stuid As 学号,Sex As 性别 INTO Stu1 FROM Stu WHERE Stuid=’20070102’
4.5.1 数据的插入 例4.42 向COURSE表一次添加多条记录。 USE Students GO INSERT Course(CouID,CouName) SELECT ‘C004’,‘太极拳’UNION SELECT ‘C005’,‘网球’UNION SELECT ‘C006’,‘书法’
4.5.2 数据的修改 UPDATE 语句可以更改表或视图中单行、多行或所有行的数据值。 UPDATE 语句的语法格式如下: UPDATE table_name | view_name SET{ column_name = { expression | DEFAULT | NULL } [ FROM { < table_source > } [ ,...n ] [ WHERE < search_condition > ]
4.5.2 数据的修改 例4.43 将课程表Course中《C语言程序设计》的上课教师修改为张大明。 USE Students GO UPDATE Course SET teachername ='张大明' WHERE Couname='C语言程序设计'
4.5.2 数据的修改 例4.44将学生表Stu中的性别全部修改为“男”。 分析:本例中是完成所有的性别修改,所以不需要使用判定条件。 USE Students GO UPDATE Stu SET sex='男'
4.5.2 数据的修改 例4.45 将电子信息系学生的‘英语’成绩增加5分。 USE Students GO UPDATE Score SET Score=Score+5 FROM Stu AS A INNER JOIN Score AS O ON S.StuID=O.StuID INNER JOIN Course AS C ON O.CouID=C.CouID WHERE DepName=‘电子信息系’AND CouName=‘英语’
4.5.3 数据的删除 DELETE 语句可删除表或视图中的一行或多行。DELETE语句格式为: DELETE table_or_view [FROM table_sources] [WHERE search_condition] FROM 子句指定删除时用到的表或视图,WHERE 子句限定被删除行的条件。该语句不从 FROM 子句指定的表中删除行,而只从DELETE指定的表中删除行。
4.5.3 数据的删除 例 4.46 删除Dep表中Depid号为111的记录。 USE Students GO DELETE Dep WHERE Depid='111'
4.5.3 数据的删除 例 4.47 将成绩表Scores中的英语成绩删除。 USE Students GO DELETE Scores Where Couid=(SELECT Couid FROM Course WHERE Couname='英语')
4.5.3 数据的删除 使用TRUNCATE TABLE语句将删除指定表中所有的数据。语法如下: TRUNCATE TABLE name DELETE 语句删除表中指定的数据,该操作可以通过事务恢复。 DROP TABLE将删除表及其数据。
4.6 综合实例应用 例4.48 从学生表Stu中查找姓刘的同学的姓名、性别、班级。 1.分析: 本例只涉及到一张数据表,所以是一种基本查询方式。但需要用到LIKE来进行模糊查询,其中模糊查询的匹配符号有许多种,在本例中将采用%的形式来代替多个字符。
4.6 综合实例应用 2、结果 SELECT Stuname As 姓名,sex As 性别,class As 班级 FROM Stu WHERE Stuname LIKE ‘刘%’
4.6 综合实例应用 例 4.49 将陈飞同学的《高等数学》成绩由84分修改为70 分。 1.分析: 在本例中需要注意有三个关键字:陈飞、高等数学、成绩。这三个关键字在一张数据表中根本不能同时找到,他们分别在Stu 、Course、Score中,所以需要对这三张数据表进行内联接查询。
4.6 综合实例应用 2.整体设计: USE Students GO UPDATE Score SET Score=70 WHERE Stuid=(SELECT Stuid FROM Stu WHERE Stuname='陈飞') and Couid=(SELECT Couid FROM Course WHERE Couname='高等数学')
4.6 综合实例应用 3.查看结果 SELECT A.Stuname As 姓名, C.Couname As 课程名称,O.Score As 分数 FROM Stu AS A INNER JOIN Scores AS O ON S.StuID=O.StuID INNER JOIN Course AS C ON O.CouID=C.CouID WHERE A.Stuname='陈飞'
本章小结 使用DISTINCT关键字去掉结果集中的重复记录。 使用TOP 返回有限的结果集。 ORDER BY子句对结果集进行排序。 GROUP BY子句对数据进行分组。 HAVING子句是对分组之后的数据进行条件限制,必须在GROUP BY之后使用。 COMPUTE子句能对结果集进行汇总。
本章小结 WHERE子句中可以使用条件表达式和逻辑表达式。 模糊查询使用LIKE关键字,有_、%、[]、 [^]四种通配符。 WHERE子句中可以使用BETWEEN…AND,IN,IS NULL等关键字实现查询条件约束。 中可以使用多表联接查询和子查询等方法实现复杂的查询。
本章小结 使用INSERT语句将数据插入表中。要考虑列数目,数据类型和能否为NULL等限制。 使用UPDATE语句修改表中的数据。 使用DELETE语句删除表中的数据。 TRUNCATE TABLE语句可以删除表中的所有数据。