【网学网提醒】:网学会员为大家收集整理了SQL数据库学习提供大家参考,希望对大家有所帮助!
重点(1—24页)SQL的组成
核心SQL主要有四个部分:
(1)数据定义语言,即SQLDDL,用于定义SQL模式、基本表、视图、索引等结构。(CREATE,ALTER,DROP,DECLARE)
(2)数据操纵语言,即SQLDML。数据操纵分成数据查询和数据更新两类。其中数据更新又分成插入、删除和修改三种操作。(SELECT,DELETE,UPDATE,INSERT)
(3)嵌入式SQL语言的使用规定。这一部分内容涉及到SQL语句嵌入在宿主语言程序中的规则。
(4)数据控制语言,即SQLDCL,这一部分包括对基本表和视图的授权、完整性规则的描述、事务控制等内容。(GRANT,REVOKE,COMMIT,ROLLBACK)
T-SQL语言创建数据库:
CREATEDATABASEmy_libraryONPRIMARY(NAME=my_library_data,FILENAME=‘c:\mssql7\data\my_library.mdf’,SIZE=10MB,MAXSIZE=15MB,FILEGROWTH=20%)LOGON(NAME=my_library_log,FILENAME=‘c:\mssql7\data\my_library.ldf’,SIZE=3MB,MAXSIZE=5MB,FILEGROWTH=1MB)//3MB的日志文件//10MB的主要数据库文件
1
T-SQL创建数据库的语句格式:
CREATEDATABASEdatabase_name[ON[PRIMARY][
[,…n]][,[,…n]]][LOGON{[,…n]}][FORLOAD∣FORATTACH]::=([NAME=logical_file_name,]FILENAME=?os_file_name?[,SIZE=size][,MAXSIZE={max_size?UNLIMITED}]
[,FILEGROWTH=growth_increment])[,…n]
::=
FILEGROUPfilegroup_name[,…n]
?PRIMARY:指定主数据文件。主要数据文件含有所有的数据库系统表,一个数据库有一个主要文件,缺省时主数据文件为给定的数据库文件。
?FILENAME:指定操作系统文件名和文件的路径。
?SIZE:指定文件的大小(缺省为xxMB)
?MAXSIZE:指定文件扩展的最大值。
?FILEGROWTH:指定文件的增长的增量。增长量可以为xxMB、KB或百分比(%)。缺省是10%,最小是64KB。
?LOGON:开始定义日志文件;
?FORLOAD表示将备份数据直接装入新建的数据库;
?FORATTACH表示从一组已经存在的文件中建立一个新数据库。
使用DROPDATABASE语句
语句格式:
DROPDATABASEdatabase_name[,…n]
可以同时删除多个数据库。
2
使用系统存储过程sp_renamedb可以修改数据库的名称,语句格式:
sp_renamedbold_dbname,new_dbname
例如:sp_renamedb?zzg?,?zzg1?
注意:
只有属于sysadmin服务器角色的成员可以给数据库更名。
在给数据库更名前,必须在企业管理器中设置该数据库为单用户状态。在单用户状态下,只能有一个用户使用该数据库,这时就不能同时打开企业管理器和查询分析器。
输入T-SQL语句,修改数据库zzg1,增加一个数据文件
alterdatabasecc1addfile(name=test1dat2,filename='c:\t1dat2.ndf',size=2mb,maxsize=5mb,filegrowth=1mb)
表是数据库中最重要的数据库对象,是数据库的基本组成部分,是储存数据的逻辑载体。关系型数据库中的表都是二维的,表的一列称为一个字段;表的一行称为一个记录。
SQLServer2000有两类表,一类是永久表,这类表一旦创建将一直存储在硬盘上,除非被用户删除;另一类是临时表,这类表在用户退出时自动被系统删除。临时表又分为局部临时表与全局临时表。局部临时表的名称以#开头,仅可由创建者本人在创建后立即使用,一旦创建者断开连接,该表将会消失;全局临时表的名称以##开头,创建者在创建后可以由多个授权用户立即使用,一旦最后使用的用户断开连接,该表将会消失。
对于表中的每一列,应该为其指定数据类型。
?1.整数数据类型
?2.货币数据类型
?3.位数据类型
?4.精确数值类型
?5.近似数值类型
?6.日期时间类型
3
?7.字符数据类型
?8.二进制数据类型
?9.统一码数据类型
?10.时间戳数据类型
?11.sql_variant数据类型
?12.表数据类型
CREATETABLE表名
(列名数据类型[缺省值][NOTNULL]
[,列名数据类型[缺省值][NOTNULL]]….
[,UNIQUE(列名[,列名]….)]
[,PRIMARYKEY(列名[,列名]…)]
[,FOREIGNKEY(列名[,列名]…)
REFERENCES表名(列名[,列名]…)]
[,CKECK(条件)])
?缺省值(DEFAULT):指定列的缺省值;
?NOTNULL:列值不能为空值;
?UNIQUE:取值唯一的列名;
?PRIMARYKEY:主关键字(主码)列名;
?FOREIGNKEY:外部码列名;
?REFERENCES:引用的外部码的表名和列名例如:产生表student,class
产生系表:
CREATETABLEclass
(classnoCHAR(8)NOTNULL,
classnameCHAR(20)NOTNULL,
PRIMARYKEY(classno)
)
CREATETABLEstudent
(snoCHAR(8)NOTNULL,
SnameCHAR(20)NOTNULL,
SsexCHAR(1),
SageINTcheck(sage>=14),
SclassCHAR(8),
PRIMARYKEY(sno),
FOREIGNKEY(sclass)
REFERENCESclass(classno)
)
CKECK:指定表约束条件。
4
使用ALTERTABLE命令修改表结构
?ALTERTABLEtable_name?{[ALTERCOLUMNcolumn_name?{new_data_type[NULL|NOTNULL]}?]?|ADDcolumn_namedata_type[NULL|DEFAULT]?|DROPCOLUMNcolumn_name[,...n]?}????命令说明:
(1)ALTERTABLE:该关键字表示本命令将修改表的结构。
(2)table_name:指定需要修改的表名称。
(3)ALTERCOLUMNcolumn_name:关键字ALTERCOLUMN表示该命令将修改表中已经存在的列属性。column_name指定需要修改的列名称。
(4)new_data_type[NULL|NOTNULL]:将表中已存在列的数据类型修改为一个新的数据类型,并可以修改其非空属性。
(5)ADDcolumn_namedata_type[NULL|DEFAULT]:指明要对表中添加的列的名称column_name及其数据类型data_type,只允许添加可包含空值NULL或指定为DEFAULT的非空值列。
(6)DROPCOLUMNcolumn_name[,...n]:关键字DROPCOLUMN指明将要删除表中已存在的一列或多列,column_name表示列名,[,...n]表示可以同时删除多列。如果列存在默认值约束或其他约束,则必须先删除它们,否则无法删除列。删除约束的方法见第10章。
(7)除DROP外,该命令一次只允许更改表的一个属性或修改一列。
??
?
?
表的修改示例①
增加外部关键字约束,例如,修改表COUSE,增加外部关键字说明,语句如下:
ALTERTABLECOUSEADDFOREIGNKEY(cdept)REFERENCESDEPT[deptno]ADDFOREIGNKEY(ctno)REFERENCESTEACHER[tno]
5
表的修改示例②
?例2,修改学生的年龄为出生日期(日期类型)。
ALTERTABLESTUDENT
ALTERsageDATETIME
?例3,增加学生的电话属性:
ALTERTABLESTUDENT
ADDsphnoCHAR(12)
?例4,增加学生的国家属性
ALTERTABLESTUDENT
ADDcountryCHAR(30)
重新命名表
用系统存储过程修改表的名称
?命令格式:
?sp_rename[@objname=]'object_name',[@newname=]'new_name?
查看表属性
?使用系统存储过程查看表属性
?使用几个有关的系统存储过程查询视图、表、存储过程等对象信息。
?(1)显示对象的名称、列名、拥有者、创建时间、列的属性等信息。
?命令格式:
?sp_help[[@objname=]name]
?命令说明:
?name为对象的名称,如果是表,则为表名称。要查询对象必须在当前数据库中。省略[@objname=]name项时显示数据库中所有对象的信息。
?(2)查看指定表与其他相关数据库对象的关联信息。
?命令格式:
?sp_depends[@objname=]name
?(3)查看数据库或表的存储空间的信息,如分配(保留)的空间量、数据使用的空间量、索引使用的空间量以及由数据库对象保留的未用空间量。
?命令格式:
?sp_spaceusedtable_name
?命令说明:
?table_name表示要查看的表名称。
6
删
?命令格式:?DROPTABLE????table_name
除表
命令说明:
(1)table_name表示要删除的表的表名称。
(2)删除表的权力仅属于表的拥有者,且不能转移。
(3)不能使用DROPTABLE命令删除系统表。
添加数据
?在SQLServer中,可以使用INSERT命令向指定的表或视图添加数据,语法如下。?命令格式:?INSERT[INTO]{table_name|view_name}?{(column_name[,...n])?{VALUES({DEFAULT|NULL|expression}[,...n])|derived_table}?}命令说明:(1)INSERT[INTO]:指定要向表中插入数据,INTO可以省略。(2){table_name|view_name}:表示要插入数据的表或视图的名称。(3)(column_name[,...n]):表示要插入数据的表或视图的列名清单。(4)VALUES:该关键字指定要插入数据的列表清单。(5){DEFAULT|NULL|expression}[,...n]:该数据列表清单中包括默认值、空值和表达式的数量、次序和数据类型必须与列清单中指定列的定义相匹配。如果在VALUES清单中按表中定义的列的顺序提供每列的值,则可以省略列清单。(6)derived_table:这是一个导入表中数据的SELECT子句。通常INSERT命令一次只能在表中插入一行数据,但可以采用SELECT子句替代VALUES子句,将一张表中的多行数据导入到要插入数据的表中。(7)尽管有时可能仅仅需要向表中插入某一(或某几)个字段数据,但是该字段所在行的其他字段一定是自动取空值、默认值和自动编号值之一,亦即插入数据是一次插入一行的。如果表中包含具有非空属性的列,则进行插入操作时必须向该字段插入数据,即在列各清单及数据列表清单中必须有其对应项,除非该列设置了默认值或自动编号等由系统自动插入数据的属性。??????
7
插入单个元组:例1:按顺序给出表中每个列值,插入一个完整的新元组,可省略表的列名。INSERTINTODEPTVALUES(?CS?,?计算机?,?888?,?10区?)例2:插入一个学生的部分列值,必须在表名后给出要输入值的列名。INSERTINTOSTUDENT(sno,sname)VALUES(?J20045?,?刘琉?)例3,建立一个新表,存放每个学生的、和平均成绩。利用查询结果插入新表中。
CREATETABLEsavg
(snoCHAR(8),snameCHAR(20),
avageREAL)
INSERTINTOsavg(sno,sname,avage)
(SELECTsc.sno,sname,AVG(grade)
FROMSC,STUDENT
WHERESC.sno=STUDENT.sno
GROUPBYsc.sno)
更新数据
?在SQLServer中,可以使用UPDATE命令在指定的表或视图中更新现有的数据,语法如下。
?命令格式:
?UPDATEtable_name
?SET
?{column_name={expression|DEFAULT|NULL}
?|@variable=expression
?|@variable=column_name=expression
?}[,...n]
?[FROM{}[,...n]]
?[WHERE]
?命令说明:?(1)UPDATEtable_name:指定需要更新的表的名称为table_name所表示的名称。
8
?(2)SET:该子句表示对指定的列或变量名称赋予新值。
?(3)column_name={expression|DEFAULT|NULL}:将变量、字符、表达式的值,或默认值,或空值替换column_name所指定列的现有值。不能修改标识列数据。
?(4)@variable=expression:指定将变量、字符、表达式的值赋予一个已经声明的局部变量。
?(5)@variable=column_name=expression:指定将变量、字符、表达式的值同时赋予一列和一个变量。
?(6)FROM{:表示要依据一个表(可以是本表或其他表)中的数据进行更新操作。
?(7)WHERE:指定修改数据的条件,如果省略此选项,则修改每一行中的该列数据。有WHERE子句时,仅修改符合WHERE条件的行。
?(8)在一个UPDATE中,可以一次修改多列的数据,只要在SET后面写入多个列名及其表达式,每个用逗号隔开。
?(9)UPDATE不能修改具有IDENTITY属性的列值。
例1,把DEPT中的计算机系的电话号码改为“9888”。UPDATEDEPTSETdeptphno=?9888?WHEREdeptno=?cs'例2,所有课程的学分都加1(1)UPDATECOUSESETcredit=credit+1用子查询进行更新操作例3,将数据库课程的成绩提高10%。
(3)UPDATESC
SETgrade=grade*110%
WHEREcno=?g008?
例4,将JS2001班学生的成绩提高10%。
(4)UPDATESC
SETgrade=grade*110%
WHERESNOin
(SELECTSNO
FROMSTUDENT
WHERE班集编号=?JS2001?)
9
删除数据
删除表中数据的方法有两种,在指定的表或视图中删除满足给定条件的数据可以使用DELETE语句;如果要清除表中全部数据,则还可以使用TRUNCATETABLE语句。DELETE语句的语法如下。????命令格式:
DELETE[FROM]{table_name|view_name}
[FROM{}]
[WHERE]
?命令说明:
?(1)DELETE语句中的语法项目含义与UPDATE语句相同。
?(2)WHERE子句给出删除数据所必须满足的条件,省略WHERE子句时将删除所有数据。
????
TRUNCATETABLE语句用于清空表中所有数据,语法如下。
命令格式:
TRUNCATETABLEtable_name
TRUNCATETABLEtable_name与DELETEtable_name都可以删除表中全部记录。
?二者的相同点是都不删除表的结构、索引、约束、规则和默认,如果希望删除表的定义,必须使用DROPTABLE语句。TRUNCATETABLE语句与DELETE语句的区别是,如果表中含有自动编号列,则使用TRUNCATE
TABLE语句后,该列将复位为其初始seed值,而使用DELETE语句将不会复位。另外,使用TRUNCATETABLE语句不记录日志,而DELETE语句每删除一条记录,都要记入日志,因此TRUNCATETABLE语句的操作速度要快于DELETE语句。
例1,只涉及单个元组,从数据库中删除某个学生李楷:
DELETEFROMSTUDENT
WHEREsname=?李楷?
例2,删除操作涉及多个元组,从数据库中删除某门课程的所有元组:
DELETEFROMSC
WHEREcno=?E001?
10
SELECT查询
????????命令格式:
SELECT[ALL|DISTINCT][TOPn[PERCENT]]select_list
[INTOnew_table]
FROMtable_source
[WHEREsearch_condition]
[GROUPBYgroup_by_expression]
[HAVINGsearch_condition]
[ORDERBYorder_expression[ASC|DESC]]
?命令说明:
?(1)ALL|DISTINCT:DISTINCT关键字用于禁止在查询结果数据集中显示重复的行。ALL关键字允许在查询结果数据集中显示查询到的全部行。默认值为ALL关键字。
?(2)TOPn[PERCENT]:TOPn用于在查询结果数据集中显示查询到的前n行数据(n为自然数);TOPnPERCENT用于在查询结果数据集中显示查询到的前百分之n行的数据。
?(3)select_list:查询所涉及到的列清单。
?(4)INTOnew_table:将查询结果集保存到新表中。
?(5)FROMtable_source:查询所涉及到的源表,即从中查询数据的表。
?(6)WHEREsearch_condition:查询条件。
?(7)GROUPBYgroup_by_expression:查询的分组汇总表达式。
?(8)HAVINGsearch_condition:分组汇总结果的筛选条件。
?(9)ORDERBYorder_expression[ASC|DESC]:查询结果集的排序准则。ASC表示查询结果升序排列,DESC表示降序排列。
使用TOP关键字
TOP子句只将前面一定的行数返回到结果集,当查询到的数据非常庞大而又没有必要对所有的数据进行浏览时,使用TOP关键字将极大地减少查询所消耗的时间。?命令格式:?TOPn[PERCENT]?命令说明:?(1)TOP关键字用于在查询结果数据集中显示查询到的前n行数据(n为整数)。?(2)PERCENT关键字用于在查询结果数据集中显示查询到的指
11
定百分比为n%的行数据。?举例
?Selecttop10*fromemployee
?Selecttop10%*fromemployee
使用DISTINCT关键字
?这是因为SELECT语句默认使用ALL关键字,ALL关键字允许在查询结果数据集中显示查询到的全部行。但有时往往不需要重复的记录,此时可以使用DISTINCT关键字从SELECT语句的结果中除去重复的行。
Selectdistinct*fromemployee
使用计算列
?如果需要对查询到的数据进行再次计算处理,可以在SELECT语句中使用计算列,计算列是一个虚拟列,它并不存在于表中,而是使用运算符对表中某一列或几列进行计算,构成计算列(列表达式)来获取经过计算的查询结果。
?举例:
?selectfirstname+”“+lastnamefromemployee
?Selectavg(job_lvl)fromemployee
使用列的别名
?在上一节使用计算列时,计算列没有显示列名,只能被系统标识成无列名。如果希望为他们加一个列名的话,可以为它加上一个别名。通过使用列的别名,可以对查询数据的列名进行修改,或是为没有名称的列加上列名。
?举例:
selectfirstname+”“+lastnameasnamefromemployee
使用WHERE子句
?用户在查询数据库时往往不需要检索全部的数据,而只需要查询其中一部分满足给定条件的信息,此时需要在SELECT语句中加入条件,以选择其中的部分记录。?WHERE子句用来指定查询返回行的条件。????命令格式:WHERE命令说明:(1)定义查询时要返回的行记录所应满足的条件表达式。SQLServer对中的查询条件数目没有限制。
12
?(2)使用时需注意,WHERE子句必须紧跟在FROM子句的后面。
例:查询全部的列,列出年龄大于20岁的学生的信息:
Select*fromstudentwhereage>20
SELECT*
FROMemployee
WHEREhire_date>?2005-01-01?
使用比较运算符
搜索pubs数据库中的title表,返回书的价格打了8折后仍然大于12美元的书名、书的类型和价格。
USEpubs
Go
SELECTtitle_id,type,price
FROMtitles
WHEREprice*0.8>12
Go
使用逻辑运算符
查询所有在美国加利福尼亚州的出版社
Usepubs
Go
SELECTpub_id,pub_name,city,state,country
FROMpublishers
WHEREcountry=?USA?andstate=?CA?
Go
使用BETWEEN关键字
例如,查询年龄在20至30之间的学生:
SELECT*
FROMstudent
WHERE年龄BETWEEN20AND30;
例如,查询年龄不在20至30之间的学生:
SELECT*
FROMstudent
WHERE年龄NOTBETWEEN20AND30;
13
使用IN关键字
?灵活的使用IN,NOTIN,ANY,ALL这些关键字,可以用简洁的语言实现较为复杂的查询,同时整个程序的可读性也会变得更好。
?例子:
Usepubs
Go
SELECTau_id,au_lname,au_fname
FROMauthors
WHEREstateIN(?CA?,?KS?,?MI?,?IN?)
Go
使用LIKE关键字
在实际的应用中,如果无法给出精确的例子,只能根据较为模糊的情况来查询数据,比如:只知道数据中含有某几个特定的字符,在这种情况下,T-SQL提供了LIKE子句和通配符进行模糊查询。通配符的使用:1.%:表示从0到n个任意字符。2._:表示单个的任意字符。3.[]:表示方括号里面列出的任意一个字符。4.[^]:表示任意一个没有在方括号里面列出的字符使用LIKE关键字举例查询所有以D开头的作家的名字:UsepubsGoSELECTau_lname+?,?+au_fnameFROMauthorsWHEREau_fnameLIKE?D%?Go//+?,?+表示在lname和fname之间增加一个逗号。输出结果如下:
Straight,Dean
Stringer,Dirk
例如,查询电话号码本中含有5737的电话号码:
14
SELECT*
FROMcalltable
WHEREcallnoLIKE?%5735%?;
例如,查询电话号码本中最后一位数是8的电话号码:
SELECT*
FROMcalltable
WHEREcallnoLIKE?%8?;
下面的例子查询所有满足au_id的前两个字母为?72?,第四个字母为?-?的作家的和电话号码:UsepubsGoSELECTau_lname,au_fname,phone,au_idFROMauthorsWHEREau_idlike?72_-%?Go如果在LIKE表达式中包含字符%或_,可以采用加上换码字符的方法解决。例如,下面的例子将匹配所有以?%?开始并以?%?结束的字符串:
sLIKE?x%%x%?ESCAPE?x?
ESCAPE?x?声明:x作为?x%%x%?的换码字符,x%指的是单独的字符%,x只起标记作用,不再表示字符。
在SQL中用两个连续的单引号表示一个单独的单引号,下面的例子表示电影名中含有?s的电影。
TitleLIKE?%??s%?
使用IS测试空值
使用IS操作符测试空值的例子,例如,从STUDENT表中查找学生电话是空值的学生名字和班级号码:
SELECTsname,sclass
FROMSTUDENT
WHEREsphnoISNULL;
输出结果如下:
sname,sclass
王者JS2001
赵良DZ2001
使用ORDERBY子句
数据库中的记录一般是按插入数据的顺序来排列的。使用ORDERBY子句可以对查询后的结果集进行排序。?命令格式:
15
?ORDERBY{order_by_expression[ASC|DESC]}[,…n]?命令说明?(1)order_by_expression是用于排序的列的名字,如果需按多列进行排序,则根据ORDERBY后各列的次序先后决定排序的优先级。?(2)ASC指定按递增顺序,DESC指定按递减顺序,ASC为默认值。?(3)在ORDERBY子句中不能使用text、ntext和image类型的字段。?(4)在ORDERBY子句中所引用列的数量不能大于SELECT语句中列的数量,否则,系统显示超出SELECT清单中列数的错误。ORDERBY子句示例
查询所有以D开头的作家的信息,并按au_lname列降序排列:
Usepubs
Go
SELECT*FROMAuthors
WHEREau_lnameLIKE?D%?
Orderbyau_lnamedesc
SQL高级查询
使用表的别名
?当表的名称太长时,为了书写上的方便简单,在SQL语言的查询语句中可以定义表的别名。?命令格式:?SELECT{table_alias.column}[,…n]?FROMtable_name[AS]table_alias[,…n]?命令说明:?(1)table_alias是表的别名。?(2)在一个SELECT语句中,系统首先执行FROM子句,然后执行SELECT,所以一旦在FROM子句中定义了表的别名,尽管SELECT子句在FROM前面,也要使用别名。(3)在一个定义了别名的SELECT语句中,从FROM子句向后是依次执行的,因此,FROM后的每一个子句只有在其前面定义了别名后才能够并且只能够使用别名。别名的作用范围仅限于本T-SQL语句中,而其他独立的T-SQL语句无权使用这个别名。举例:SELECTs.sno,s.sname,sc.gradeFROMstudents,sc,coursecWHEREscame=?DATASTRUCTURE?ANDsc.grade<60
16
ANDcouseo=scoANDsc.sno=s.sno;
*
多表查询
如果希望从多个表中获取查询结果,例如从Student表中获取学生的,从Score表中获取学生的成绩,那么就需要在多个表中选择和操作数据,这正是SQL的特色之一。
内连接
?内连接(InnerJoin)也叫自然连接,是指将另一个表内的行数据与本表内的数据相互连接,产生的结果行数取决于参加连接的行数,也就是说在将两个表中的指定列进行比较时,仅将两个表中满足连接条件的行组合起来作为结果集。在内连接中,只有在两个表中匹配的行才能在结果集中出现。1.在WHERE子句中指定连接?在WHERE子句中可以使用比较运算符(=、<、>等)指定连接的条件。在两个表之间进行内连接的语法如下。?命令格式:?SELECTselect_list?FROMtable1,table2?WHEREtable1.column1=table2.column2?命令说明:?(1)select_list表示查询内容的列表。?(2)在FROM子句中指定查询数据的两个表table1与table2,表的顺序可以任意排列。?(3)在WHERE子句中指定了连接的条件,当使用“=”连接时,通常也称为等值连接,它只显示第一个表和第二个表中满足连接条件的数值。例1:列出所有任课教师的名字,去掉重复值:
SELECTDISTINCTtname任课教师
FROMCOUSE,TEACHER
WHERECOUSE.tno=TEACHER.tno
输出结果如下:
任课教师
王学
李力
张三
查询JS2001班学生和其选修课程情况:
17
SELECTSTUDENT.sno,sname,ssex,sage,sclass,cno,gradeFROMSC,STUDENTWHERESTUDENT.sno=SC.snoANDsclass=“JS2001”输出结果如下:J20001李楷m19JS2001G00178J20002张会f20JS2001G00285J20003王者m20JS2001E00186自然连接
例2:统计各科成绩的最低、最高分和平均成绩,及课程名。
SELECT
CNAME,MIN(grade),MAX(grade),AVG(grade)
FROMSC,COUSE
WHERESCo=COUSEo
GROUPBYcname
输出结果如下:
CNAME,MIN(grade),MAX(grade),AVG(grade)
Vc609275
汇编659078
数据结构609472
2.使用JOIN和ON关键字指定连接条件?在使用SELECT语句时,还可以使用JOIN和ON关键字建立连接条件。?命令格式:?SELECTselect_list?FROMtable1[INNER]JOINtable2?ONtable1.column1=table2.column2?命令说明:?(1)FROM子句指定连接的两个表。?(2)[INNER]JOIN表示两个表的连接方式为内连接。INNER是默认方式,可以省略。?(3)ON用于给出这两个表之间的连接条件。举例:使用JOIN连接不同的表,使用ON给出两个表之间的连接条件。这是ANSI92标准进行多表查询的书写方式。例如,前面的例子可以改写如下:SELECTs.sno,s.sname,sc.gradeFROMstudentsJOINscONsc.sno=s.snoJOINcoursecONco=sco
18
WHEREscame=?DATASTRUCTURE?
ANDsc.grade<60
选择出大于平均销售数量的书的名字,价格:
SELECTtitles.title,titles.price
FROMtitlesJOINsalesONsales_id=titles_id
WHEREsales.qty>
(SELECTAVG(qty)
FROMsales)
使用UNION子句
使用UNION子句的查询称为联合查询,它可以将两个或更多查询的结果集组合为一个单个结果集,该结果集包含联合查询中所有查询结果集中的全部行数据。联合查询不同于对两个表中的列进行连接查询,前者是组合两个表中的行,后者是匹配两个表中的列数据。?联合查询必须注意两个问题,首先是每一个查询结果集都必须与第一个查询结果集具有相同数量的列,其次是各个查询结果集中的列数据类型必须与第一个查询结果集中对应的列数据类型相兼容。?命令格式:?select_statement?UNION[ALL]select_statement?[UNION[ALL]select_statement][...n]?命令说明:?(1)本命令将多条查询语句的查询结果按照查询语句select_statement的先后次序显示。?(2)查询结果的标题为第一个select_statement的标题。?(3)UNION子句会自动删除查询结果中重复的行。如果希望获得所有的行,可在UNION的后面加上关键字ALL。?(4)UNION子句只是要求每一个查询中的列与第一个查询的列的数据类型兼容,并不要求完全相同。例如:Student表中的name列是varchar(20),而Score表中subjectid列是char(4),这两列也可以正常地进行联合查询。?(5)如果要对查询后的组合结果集排序的话,必须把ORDERBY子句写在最后一个select_statement后,但排序必须依据第一个select_statement中的列。举例:SELECT查询的结果是元组的集合,多个查询结果可以进行集合的并(UNION)操作。例如,查询选修了课程G001和选修了课程E001的学生的。SELECTsnoFROMscWHEREcno=“G001”
19
UNION
SELECTsno
FROMsc
WHEREcno=“E001”
使用统计函数
?在SELECT语句中除了可以使用算术表达式进行列计算外,还可以使用一系列的统计函数对表中的所有数据进行汇总、统计等多种运算,统计函数属于聚合函数(AggregateFunction)。?统计函数通常用于SELECT语句中,作为结果集中的返回列。在SELECT语句中使用统计函数的语法如下。?命令格式:?SELECTfunction_name({column_name|@variable}[,...n])[,...n]?FROMtable_List?命令说明:?(1)function_name表示函数的名称。?(2)(column_name|@variable)表示针对其进行函数运算的列名称或变量名称。如果函数需要一个以上的自变量,则用逗号进行分隔。SUM函数?SUM函数返回列或表达式中所有值的总和,此函数只能用于数值型的字段。当列中的值为NULL时,该空值在计算求和时将被忽略。?命令格式:?SUM([ALL|DISTINCT]expression)?命令说明:?(1)ALL表示对所有的值进行聚合函数运算,是默认设置。?(2)DISTINCT表示仅对不同的值进行聚合函数运算,而不管该值出现了多少次。?(3)expression表示对数字数据类型的表达式进行运算。AVG函数?AVG函数返回列或表达式中的算术平均值,此函数只能用于数值型的字段。?命令格式:?AVG([ALL|DISTINCT]expression)?命令说明:各语法项目与SUM类同。COUNT函数?COUNT函数返回列中的记录个数。?命令格式:?COUNT([ALL|DISTINCT]column_name|*)?命令说明:
20
?(1)在COUNT函数中引用一个列名column_name时,将返回该列中行记录的个数。?(2)COUNT函数默认使用ALL参数,它将重复计算相同的值,但不包含值为NULL的行。?(3)使用DISTINCT时,相同的值只计数一次,且不包含NULL值。?(4)在COUNT函数中可以使用*做参数,它表示返回表中的所有行数,包括含有NULL值的行。MAX函数与MIN函数
?MAX函数返回某一列中的最大值,它可用于数字列、字符列和datetime列,但不能用于BIT列。
?命令格式:
?MAX([ALL|DISTINCT]expression)
?MIN函数返回某一列中数据的最小值,其使用方法与MAX函数相同。
使用GROUPBY子句
?如果希望将查询结果按某一列或几列进行分类统计,即不同的列值被放到不同的组中时,可以使用GROUPBY子句。基本命令结构如下。?命令结构:?SLETCTcolumn_name[,...n]?FROMtable_name?GROUPBY[ALL]column_name[,...n]?命令说明:?(1)在SELECT语句中所指定的列必须是GROUPBY子句中的列名,或是被聚合函数所使用的列。?(2)ALL关键字,它指定返回由GROUPBY子句产生的所有组,即使某些组没有符合WHERE子句中指定条件的行。?(3)text、ntext和image类型的列不能用于GROUPBY子句。?(4)分组的列中包含多个NULL时,这些空值将放入一个组中进行显示。?(5)在GROUPBY子句中必须使用列的名称,而不是使用AS子句指定的列别名。例如1:查询学生的总人数,SELECTCOUNT(*)FROMstudent;例如2:查询选修了课程的学生总人数,SELECTCOUNT(DISTINCTsno)FROMsc;使用聚合函数查询,统计某个列中值的个数例如,求每个班级男生的人数,必须按班号分组,而后按班统计学生人数:SELECT班号,COUNT(*)
21
FROMstudentWHERE性别=‘男’GROUPBY班号输出结果如下:班号,COUNT(*)js990121js990222js990325js990420使用聚合函数查询,求列的最大最小值例如,列出所有学生的最小和最大年龄:SELECTMIN(sage),MAX(sage)FROMSTUDENT输出结果如下:MIN(sage),MAX(sage)1425使用聚合函数查询,查询结果分组
例如,统计各科成绩的最低、最高分和平均成绩。
SELECT
CNO,MIN(grade),MAX(grade),AVG(grade)
FROMSC
GROUPBYcno
输出结果如下:
CNO,MIN(grade),MAX(grade),AVG(grade)
G006609275
G007659078
G002609472
使用HAVING子句
?在完成指定条件的查询后,还可以使用HAVING子句来对分组的结果进行进一步的筛选。下面是HAVING子句的语法结构。?命令格式:?HAVING?命令说明:?(1)指定分组所应满足的条件。?(2)用HAVING子句对GROUPBY子句设置条件的方式与WHERE子句对SELECT语句设置条件的方式类似,但HAVING可以包含聚合函数。如果HAVING中包含多个条件,那么这些条件将通过AND、OR或NOT组合在一起。举例:例如,查询学分不到20分的学生的和学分总数。
22
SELECT,SUM(credit)FROMSC,COURSEWHEREgrade>=60ANDgradeNOTNULLANDSCo=COURSEoGROUPBYHAVINGSUM(credit)<20例2:统计平均成绩大于75分的科目的最低、最高分和平均成绩,及课程名。
SELECT
CNAME,MIN(grade),MAX(grade),AVG(grade)
FROMSC,C
WHERESCo=Co
GROUPBYcname
HAVINGAVG(GRADE)>75
输出结果如下:
CNAME,MIN(grade),MAX(grade),AVG(grade)
汇编659078
使用嵌套查询
?在一个SELECT语句中嵌入另一个完整的SELECT语句称为嵌套查询。嵌入的SELECT语句称为子查询,而包含子查询的SELECT语句称为外部查询。子查询自身可以包括一个或多个子查询,也可以嵌套任意数量的子查询。?但子查询中返回的数据类型是有限制的,它不能使用image和text等数据类型,并且子查询返回的数据类型还必须和外部查询WHERE子句中的数据类型相匹配。?子查询既可以嵌套在SELECT语句中,也可以嵌套在UPDATE、DELETE和INSERT语句中。举例:例1,列出与李楷同班的同学的全部信息:SELECT*FROMSTUDENTWHEREsclass=(SELECTsclassFROMSTUDENTWHEREsname=“李楷”);输出结果如下:snosnamessexsagesclassJ20001李楷m19JS2001J20002张会f20JS2001J20003王者m20JS2001例2,查找高于职工平均工资的职工信息:
23
SELECT*FROMemptableWHEREsalary>(SELECTAVG(salary)FROMemptable)查询本学期选课超过8门的学生人数,没有成绩的选课表示本学期正在选修的课程。SELECTCOUNT(*)FROMstudentWHEREsnoIN注:选课>8的集(SELECTsno选课的FROMscWHEREgradeISNULLGROUPBYsno注:按分组HAVINGCOUNT(*)>8);使用比较运算符的子查询?子查询可由一个比较运算符(=、<>、>、>=、<、!>、!<或<=)引入做为比较运算符的条件,子查询必须返回单个值做为外部查询中WHERE子句的比较参数。使用IN的子查询
?使用IN(或NOTIN)关键字引入子查询时,允许子查询返回一列零值或多个结果值。它判断IN关键字前所指定的列值是否在子查询的结果中,IN是嵌套查询中最常用的关键字。
举例:
SELECTdname,deptno
FROMdept
WHEREdeptnoNOTIN
(SELECTdeptnoFROMemp);
使用EXISTS的子查询
使用EXISTS关键字引入一个子查询时,就相当于进行一次数据是否存在的测试。为了便于理解,我们可以把EXISTS想象为一个函数,而子查询是这个EXISTS函数的参数。它的作用是在WHERE子句中测试子查询返回的行是否存在。EXISTS子查询实际上不产生任何数据,它只返回TRUE或FALSE值。举例:?SELECTdname,deptnoFROMdeptWHERENOTEXISTS(SELECTdept.deptnoFROMemp,dept
24
WHEREdept.deptno=emp.deptno);
非重点视图的创建和撤销
?视图的创建创建视图可用“CREATEVIEW”语句实现。其句法如下:CREATEVIEW<视图名>(列表名)AS