第三章:关系数据库标准语言SQL
数据库查询
1 SELECT语句语法格式 结果集中可以包含重复行 结果集中只能包含唯一行 SELECT[ALL|DISTINCT] 从基本结果集中返回额外的行 [TOP(expression)[PERCENT][WITHTIES]]
/*指定要选择的列及其限定*/
[INTOnew_table]
/*INTO子句,指定结果存入新表*/
[FROMtable_source]
/*FROM子句,指定表或视图*/
[WHEREsearch_condition]
/*WHERE子句,指定查询条件*/
[GROUPBYgroup_by_expression]
/*GROUPBY子句,指定分组表达式*/
[HAVINGsearch_condition]
/*HAVING子句,指定分组统计条件*/
[ORDERBYorder_expression[ASC|DESC]]
/*ORDERBY子句,指定排序表达式和顺序*/
升序
降序
2 SELECT语句的处理顺序
1 FROM
2 ON
3 JOIN
4 WHERE
5 GROUPBY
6 WITHCUBE或WITHROLLUP
7 HAVING
8 SELECT
9 DISTINCT 10ORDERBY 11TOP 所有被使用的子句必须按语法说明中显示的顺序严格的排序。
3 SELECT_list语句语法格式::={
返回标识列
返回行GUID列
*
/*选择当前表或视图的所有列*/
|{table_name|view_name|table_alias}.*
/*选择指定的表或视图的所有列*/
|{{column_name|$IDENTITY|$ROWGUID}
/*选择指定的列*/
|udt_column_name[{.|::}{{property_name|field_name}|method_name(argument[,...n])}]
用户定义类型
*/列的名称
用户定义类型的方法、属性或字段
/*选择用户定义数据类型的属性、方法和字段
|expression[[AS]column_alias]}
替换列名的可选名
/*AS子句,定义列别名*/
|column_alias=expression
/*选择指定列并更改列标题*/
}[,...n]
4 1、选择所有列EG:查询PXSCJ数据库中XSB表的所有数据。
SELECT*FROMXSB;
2、选择表中指定的列EG:查询PXSCJ数据库的XSB表中各个同学的姓名、专业和总学分。
SELECTXSB.Stu_ID,XSB.Sname,XSB.TcreditFROMXSB;
3、消除结果集中的重复行EG:查询XSB表中的专业,消除结果集中重复行。
SELECTDISTINCTXSB.MajorFROMXSB;比较:查询XSB表中的专业和性别,消除结果集中重复行。
SELECTDISTINCTXSB.Major,XSB.SsexFROMXSB;
5 4、定义列别名EG:查询XSB表中学生的学号、姓名和总学分,结果中各列的标题分别指定为“学号”、“姓名”和“总学分”。
SELECTXSB.Stu_IDAS学号,XSB.SnameAS姓名,XSB.TcreditAS总学分FROMXSB;
5、限制结果集返回行数EG:查询XSB表中学生的姓名、专业和总学分,返回结果集的前6行。
SELECTTOP
(6)XSB.Sname,XSB.Major,XSB.TcreditFROMXSB;比较:查询XSB表中学生的姓名、专业和总学分,返回结果集的前6%行。
SELECTTOP
(6)PERCENTXSB.Sname,XSB.Major,XSB.TcreditFROMXSB;
6 6、替换查询结果中的数据EG:查询XSB表中学生的学号、姓名和总学分,对总学分按以下规则替换:若总学分为空值,则替换为“尚未选课”;若总学分小于50,则替换为“不合格”;若总学分在50与52之间,则替换为“合格”;若总学分大于52,则替换为“优秀”。
列标题更改为“等级”。
SELECTXSB.Stu_ID,XSB.Sname,等级=CASEWHENXSB.TcreditISNULLTHEN'尚未选课'WHENXSB.Tcredit<50THEN'不合格'WHENXSB.Tcredit>=50andXSB.Tcredit<=52THEN'合格'ELSE'优秀'ENDFROMXSB;
7 7、计算列值EG:按150分计算成绩并查询学生的成绩情况。
SELECTCJB.Stu_ID,CJB.C_ID,成绩=CJB.Grade*1.5FROMCJB;比较:SELECTCJB.Stu_ID,CJB.C_ID,CJB.Grade=CJB.Grade*1.5 FROMCJB;
8、聚合函数
(1)SUM和AVGSUM/AVG([ALL|DISTINCT]expression)SUM/AVG在计算时,忽略NULL值。
8 EG:求学号为081101的学生所学课程的平均成绩和总成绩。
SELECTAVG(CJB.Grade)AS平均成绩,SUM(CJB.Grade)AS总成绩FROMCJBWHERECJB.Stu_ID='081101';
(2)MAX和MINMAX/MIN([ALL|DISTINCT]expression)MAX/MIN在计算时,忽略NULL值。
EG:求选修101课程的学生的最高分和最低分。
SELECTMAX(CJB.Grade)AS最高分,MIN(CJB.Grade)AS最低分FROMCJBWHERECJB.C_ID='101';
9
(3)COUNTCOUNT{([ALL|DISTINCT]expression)|*}COUNT在计算时,忽略NULL值;COUNT(*)返回总数目,包含空值。
EG:求学生的总数。
SELECTCOUNT(*)FROMXSB; EG:统计备注不为空的学生数。
SELECTCOUNT(XSB.Remark)FROMXSB; EG:求选修了课程的学生总数。
SELECTCOUNT(DISTINCTCJB.Stu_ID)FROMCJB; 10 WHERE子句语法格式 [WHERE]
/*结果集中返回的行的条件*/
::=
判定运算
{[NOT]|()}
[{AND|OR}[NOT]{|()}]
[,...n]
判定运算包括比较运算、模式匹配、范围比较、空值比较、CONTAIN谓词、FREETEXT谓词和子查询。
11 WHERE子句语法格式::=
{expression{=|<>|!
=|>|>=|!
>|<|<=|!
<}expression /*比较运算*/ |string_expression[NOT]LIKEstring_expression[ESCAPE'escape_character']/*字符串模式匹配*/ |expression[NOT]BETWEENexpressionANDexpression /*指定范围*/ |expressionIS[NOT]NULL搜索指定的单词、短语等 /*是否空值判断*/ |CONTAINS({column|*},'')
/*包含式查询*/
|FREETEXT({column|*},'freetext_string')搜索指定的单词、短语等
/*自由式查询*/
|expression[NOT]IN(subquery|expression[,...n])
/*IN子句*/
|expression{=|<>|!
=|>|>=|!
>|<|<=|!
<}{ALL|SOME|ANY}(subquery) /*比较子查询*/ |EXISTS(subquery)}/*EXIST子查询*/ 12
1、表达式比较 {expression{=|<>|!
=|>|>=|!
>|<|<=|!
<}expression /*比较运算*/ EG:查询PXSCJ数据库XSB表中学号为081101的同学的情况。
SELECTXSB.*FROMXSBWHEREXSB.Stu_ID='081101'; EG:查询XSB表中总学分大于50的同学的情况。
SELECTXSB.*FROMXSBWHEREXSB.Tcredit>50; EG:查询XSB表中通信工程专业总学分大于等于52的同学的情况。
SELECTXSB.*FROMXSBWHEREXSB.Major='通信工程'ANDXSB.Tcredit>=52; 13
2、模式匹配 string_expression[NOT]LIKEstring_expression[ESCAPE'escape_character']/*字符串模式匹配*/ 字符串和通配符 允许在字符串中搜索通配符 通配符列表 通配符 说明 示例 包含零个或多个字符的任WHEREtitleLIKE'puter%' % 意字符串。
将查找在书名中任意位置包含单词puter"的所有书名。
_(下划线)任何单个字符。
WHEREau_fnameLIKE'_ean'将查找以ean结尾的所有4个字母的名字(Dean、Sean等)。
WHEREau_lnameLIKE'[C-P]arsen' 指定范围([a-f])或集合 将查找以arsen结尾并且以介于C与P之间的任何单个字符开始的作者姓氏, [] ([abcdef])中的任何单个字 例如Carsen、Larsen、Karsen等。
在范围搜索中,范围包含的字符可能因排 符。
序规则的排序规则而异。
不属于指定范围([a-f])或 WHEREau_lnameLIKE'de[^l]%' [^] 集合([abcdef])的任何单个 将查找以de开始并且其后的字母不为l的所有作者的姓氏。
字符。
14 EG:查询PXSCJ数据库XSB表中姓“王”且单名的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SnameLIKE'王_'; EG:查询XSB表中学号倒数第3个数字为
1,且倒数第1个数在1~5之间的学生的学号、姓名和专业。
SELECTXSB.Stu_ID,XSB.Sname,XSB.MajorFROMXSBWHEREXSB.Stu_IDLIKE'%1_[12345]'; EG:查询XSB表中名字包含%的学生学号和姓名。
SELECTXSB.Stu_ID,XSB.SnameFROMXSBWHEREXSB.SnameLIKE'%#%%'ESCAPE'#'; 定义转义字符 15 比较: EG:查询PXSCJ数据库XSB表中姓“王”且全名为3个汉字的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SnameLIKE'王__'; EG:查询PXSCJ数据库XSB表中姓“王”且全名为3个汉字的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SnameLIKE'王%‘andlen(Sname)=3;; 16
3、范围比较 |expression[NOT]BETWEENexpressionANDexpression/*指定范围*/ expression[NOT]IN(subquery|expression[,...n]) /*IN子句*/ EG:查询PXSCJ数据库XSB表中不在1989年出生的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SdateNOTBETWEEN'1989-1-1'AND'1989-12-31'; EG:查询XSB表中专业为“计算机”、“通信工程”或“无线电”的学生情况。
SELECTXSB.*FROMXSBWHEREXSB.MajorIN('计算机','通信工程','无线电'); 17
4、空值比较|expressionIS[NOT]NULL /*是否空值判断*/ 不使用NOT时,若表达式expression的值为空值,则返回TRUE,否则返回FALSE;使用NOT时,结果相反。
EG:查询PXSCJ数据库XSB表中总学分尚不定的学生情况。
SELECTXSB.*FROMXSBWHEREXSB.TcreditISNULL; 18
5、子查询 子查询除了可以用在SELECT语句中,也可以用在INSERT、UPDATE和DELETE语句中。
通常与IN、EXIST谓词及比较运算符结合使用。
(1)IN子查询 |expression[NOT]IN(subquery) /*IN子句*/ 用于进行一个给定值是否在子查询结果集中的判断。
当表达式expression与子 查询subquery的结果表中的某个值相等时,IN谓词返回TRUE,否则返回 FALSE;使用了NOT,则相反。
EG:查询选修了课程号为206的课程的学生基本情况。
SELECT
XSB.*FROMXSBWHEREXSB.Stu_IDIN(SELECTCJB.Stu_IDFROMCJB 系统先执行子查询,产生一个结果表,再执行查询。
WHERECJB.C_ID='206');19 EG:查询未选修离散数学的学生情况。
SELECTXSB.*FROMXSB WHEREXSB.Stu_IDNOTIN ( SELECTCJB.Stu_ID FROMCJB WHERECJB.C_IDIN ( SELECTKCB.C_ID FROMKCB WHEREKCB.Cname='离散数学' ) ); 20
(2)比较子查询expression{=|<>|!
=|>|>=|!
>|<|<=|!
<}{ALL|SOME|ANY}(subquery) /*比较子查询*/ ALL:指定表达式要与子查询结果集中的每个值都进行比较,满足时返回TRUE,否则返回FALSE; SOME或ANY:表达式只要与子查询结果集中的某个值满足比较的关系,就返回TRUE,否则返回FALSE。
EG:查询选修了离散数学的学生学号。
SELECTCJB.Stu_IDFROMCJBWHERECJB.C_IDIN (SELECTKCB.C_IDFROMKCB 可否将IN改为“=”? WHEREKCB.Cname='离散数学'); 21 EG:查找比所有计算机系的学生年龄都大的学生。
SELECTXSB.*FROMXSBWHEREXSB.SdateSELECTCJB.Stu_IDFROMCJBWHERECJB.C_ID='206'ANDCJB.Grade!
(3)EXISTS子查询
[NOT]EXISTS(subquery)
/*EXIST子查询*/
EXISTS谓词用于测试子查询的结果是否为空表,若结果集不为空,则返回
TRUE,否则返回FALSE;与NOT结合使用,其返回值相反。
由EXISTS引入的子查询的选择列表通常几乎都是由星号(*)组成。
由于只是 测试是否存在符合子查询中指定条件的行,因此不必列出列名。
EG:查询选修了206号课程的学生姓名。
SELECTXSB.SnameFROMXSBWHEREEXISTS (SELECTCJB.*FROMCJB WHERECJB.Stu_ID=XSB.Stu_IDANDCJB.C_ID='206'); 处理过程:①查找外层查询中XSB表的第一行,根据学号值处理内层查询;②若结果不为空,则取出该行姓名值作为结果集的一行③依次查找外层查询的2、3、4……行,直至XSB中所有行查找完为止。
24 EG:查询没有选修206号课程的学生姓名。
SELECTXSB.SnameFROMXSBWHERENOTEXISTS(SELECTCJB.*FROMCJBWHERECJB.Stu_ID=XSB.Stu_IDANDCJB.C_ID='206'); 比较: SELECTXSB.SnameFROMXSBWHEREXSB.Stu_IDNOTIN(SELECTCJB.Stu_IDFROMCJBWHERECJB.C_ID='206'); SELECTXSB.SnameFROMXSBWHEREXSB.Stu_ID<>(SELECTCJB.Stu_IDFROMCJBWHERECJB.C_ID='206'); 25 EG:查询选修了全部课程的学生姓名。
(没有一门课程是他不选修的。
)SELECTXSB.SnameFROMXSBWHERENOTEXISTS( SELECT*FROMKCBWHERENOTEXISTS (SELECT*FROMCJBWHERECJB.Stu_ID=XSB.Stu_IDANDCJB.C_ID=KCB.C_ID )); 26 SELECT关键字后面也可以定义子查询。
EG:从XSB表中查找所有女生的姓名、学号及其与081101号学生的年龄差距。
SELECTXSB.Sname,XSB.Stu_ID,YEAR(XSB.Sdate)-YEAR((SELECTXSB.SdateFROMXSBWHEREXSB.Stu_ID='081101'))AS年龄差距FROMXSBWHEREXSB.Ssex=0; 27 ANY(或SOME)、ALL谓词与聚集函数、IN谓词的转换 ANYALL = <>或!
= < <= > >= IN ----MIN>=MIN
----
NOTINMAX>=MAX
聚集函数实现子查询通常比直接用ANY或者ALL查询效率高。
28 FROM子句语法格式 [FROM{}[,...n]]
::=
{
table_or_view_name[[AS]table_alias]
[WITH([[,]...n])]
|rowset_function[[AS]table_alias]
[(bulk_column_alias[,...n])]
返回用户自定义函数
|user_defined_function[[AS]table_alias]]
|OPENXML
必须使用AS为子查询产生的中间表定义一个别名
|derived_table[AS]table_alias[(column_alias[,...n])]
||
执行子查询返回的表
|
}
/*查询表或视图,可指定别名*//*指定查询优化器对此表和此语句使用优化或锁定策略*//*指定其中一个行集函数(如OPENROWSET)*//*代替结果集内列名的可选别名*//*指定表值函数*//*通过XML文档提供行集视图*//*子查询*//*连接表*//*将行转换为列*//*将列转换为行*/
29
1、table_or_view_name[[AS]table_alias]/*查询表或视图,可指定别名*/指定SELECT语句要查询的表或视图,表和视图可以是一个或多个。
EG:从KCB表中查找101号课程的开课学期。
SELECTKCB.TermFROMKCBWHEREKCB.C_ID='101'; EG:查找081101号学生计算机基础课的成绩。
SELECTCJB.GradeFROMCJB,KCBWHERECJB.Stu_ID='081101'ANDKCB.Cname='计算机基础'AND KCB.C_ID=CJB.C_ID; 30 EG:查询选修了学号为081102的同学所选修的全部课程的学生的学号。
(081102学生选修的课程没有一门是他不选修的。
)SELECTDISTINCTCJ1.Stu_IDFROMCJBASCJ1WHERENOTEXISTS( SELECT*FROMCJBASCJ2WHERECJ2.Stu_ID='081102'ANDNOTEXISTS (SELECT*FROMCJBASCJ3WHERECJ3.Stu_ID=CJ1.Stu_IDANDCJ3.C_ID=CJ2.C_ID )); 31 2、derived_table[AS]table_alias[(column_alias[,...n])] /*子查询*/ 子查询可以在FROM子句中使用,derived_table表示执行子查询返回的表,必须使用AS关键字为子查询产生的表定义一个别名。
EG:从XSB表中查找总学分大于50的男生的姓名和学号。
SELECTSTUDENT.Stu_ID,STUDENT.SnameFROM(SELECTXSB.*FROMXSBWHEREXSB.Tcredit>50)ASSTUDENTWHERESTUDENT.Ssex=1;SELECTXSB.Stu_ID,XSB.SnameFROMXSBWHEREXSB.Tcredit>50ANDXSB.Ssex=1; SELECTXSB.Stu_ID,XSBT.SnameFROM(SELECTXSB.*FROMXSBWHEREXSB.Tcredit>50)ASSTUDENTWHEREXSB.Ssex=1;32 EG:在XSB表中查找1990年1月1日以前出生的学生的姓名和专业,分别使用name和speciality表示。
SELECTm.name,m.specialityFROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101')ASm(num,name,sex,birthday,speciality,score,mem);SELECTm.Snamename,m.MajorspecialityFROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101')ASm; SELECTm.SnameASname,m.MajorASspecialityFROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101')ASm; SELECTm.name,m.speciality FROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101') ASm(name,speciality); 33 连接查询(涉及多个表的查询) 在T-SQL中,连接查询有两大表示形式:符合SQL标准的连接谓词表示形式;T-SQL扩展的,使用JOIN关键字的表示形式。
1、连接谓词在SELECT语句的WHERE子句中使用比较运算符给出连接条件对表进行连接。
EG:查找PXSCJ数据库每个学生的基本情况以及选修的课程情况。
SELECTXSB.*,CJB.*FROMXSB,CJBWHEREXSB.Stu_ID=CJB.Stu_ID;比较: SELECTXSB.*,CJB.C_ID,CJB.GradeFROMXSB,CJBWHEREXSB.Stu_ID=CJB.Stu_ID; 34 EG:查找选修了206号课程且成绩在80分以上的学生姓名及成绩。
SELECTXSB.Sname,CJB.GradeFROMXSB,CJBWHEREXSB.Stu_ID=CJB.Stu_IDANDCJB.C_ID='206'ANDCJB.Grade>=80; EG:查找选修了“计算机基础”课程且成绩在80分以上的学生学号、姓名、课程名及成绩。
SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSB,KCB,CJBWHEREXSB.Stu_ID=CJB.Stu_IDANDKCB.C_ID=CJB.C_IDANDKCB.Cname='计算机基础'ANDCJB.Grade>=80; 35 连接查询和子查询的区别:连接查询可以合并两个或多个表中的数据;带子查询的SELECT语句的结果只能来自一个表。
36
2、以JOIN关键字指定的连接::=
{要连接的表
连接类型
连接条件
ON
|CROSSJOIN
}
交叉连接
::=
[{INNER|{{LEFT|RIGHT|FULL}[OUTER]}}[]]
JOIN
37
以JOIN关键字指定的连接有三种类型:内连接、外连接、交叉连接。
(1)内连接(INNERJOIN)EG:查找PXSCJ数据库每个学生的基本情况以及选修的课程情况。
SELECT*FROMXSBINNERJOINCJBONXSB.Stu_ID=CJB.Stu_ID; SELECT*FROMXSBJOINCJBONXSB.Stu_ID=CJB.Stu_ID; 执行结果将包含XSB表和CJB表的所有字段(不去除重复字段)。
38 EG:查询选修了206号课程且成绩在80分以上的学生姓名和成绩。
SELECTXSB.Sname,CJB.GradeFROMXSBJOINCJBONXSB.Stu_ID=CJB.Stu_IDWHERECJB.C_ID='206'ANDCJB.Grade>=80; EG:查找不同课程成绩相同的学生的学号、课程号和成绩。
(自连接)SELECTa.Stu_ID,a.C_ID,b.C_ID,a.GradeFROMCJBaJOINCJBbONa.Grade=b.GradeANDa.Stu_ID=b.Stu_IDAND a.C_ID!
=b.C_ID; 39 EG:查找选修了“计算机基础”课程且成绩在80分以上的学生学号、姓名、课程名和成绩。
SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSBJOINCJBJOINKCBONCJB.C_ID=KCB.C_IDONXSB.Stu_ID=CJB.Stu_IDWHEREKCB.Cname='计算机基础'ANDCJB.Grade>=80; SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSBJOINCJBONXSB.Stu_ID=CJB.Stu_IDJOINKCBONCJB.C_ID=KCB.C_IDWHEREKCB.Cname='计算机基础'ANDCJB.Grade>=80; SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSBJOINCJBJOINKCBONXSB.Stu_ID=CJB.Stu_IDONCJB.C_ID=KCB.C_IDWHEREKCB.Cname='计算机基础'ANDCJB.Grade>=80; 40
(2)外连接(OUTERJOIN)外连接的结果表不但包含满足连接条件的行,还包括相应表中的所有行。
左外连接(LEFTOUTERJOIN):结果表中除了包括满足连接条件的行外,还包括左表的所有行;右外连接(RIGHTOUTERJOIN):结果表中除了包括满足连接条件的行外,还包括右表的所有行;完全外连接(FULLOUTERJOIN):结果表中除了包括满足连接条件的行外,还包括两个表的所有行;其中OUTER关键字可以省略。
41 EG:查找所有学生情况,以及他们选修的课程号,若学生未选修任何课,也要包括其情况。
SELECTXSB.*,CJB.C_IDFROMXSBLEFTJOINCJBONXSB.Stu_ID=CJB.Stu_ID; SELECTXSB.*,CJB.C_IDFROMCJBRIGHTJOINXSBONXSB.Stu_ID=CJB.Stu_ID;EG:查找被选修了的课程的选修情况和所有开设的课程名。
SELECTCJB.*,KCB.CnameFROMCJBRIGHTJOINKCBONCJB.C_ID=KCB.C_ID; SELECTCJB.*,KCB.CnameFROMKCBLEFTJOINCJBONCJB.C_ID=KCB.C_ID; 42
(3)交叉连接(CROSSJOIN)将两个表进行笛卡尔积运算,结果表由第一个表的每一行与第二个表的每一行拼接后形成的表。
EG:列出学生所有可能的选课情况。
SELECTXSB.Stu_ID,XSB.Sname,KCB.C_ID,KCB.CnameFROMXSBCROSSJOINKCB; EG:列出软件工程学生所有可能的选课情况。
SELECTXSB.Stu_ID,XSB.Sname,KCB.C_ID,KCB.CnameFROMXSBCROSSJOINKCBWHEREXSB.Major='软件工程'; 43 GROUPBY子句语法格式 [GROUPBYgroup_by_expression]/*GROUPBY子句,指定分组表达式*/ GROUPBY子句具有符合ISO的语法和不符合ISO的语法。
在一条SELECT语句中只能使用一种语法样式。
对于所有的新工作,请使用符合ISO的语法。
提供不符合ISO的语法的目的是为了实现向后兼容。
1、非ISO标准的GOURPBY子句 分组表达式 [GROUPBY[ALL]group_by_expression[,...n] [WITH{CUBE|ROLLUP}]] 指定CUBE、ROLLUP操作 指定结果集内不仅包含由GROUPBY提供的行,同时还包含汇总行。
44 EG:输出PXSCJ数据库中各专业名。
SELECTXSB.MajorFROMXSBGROUPBYXSB.Major; 比较:SELECTXSB.MajorFROMXSB; SELECTDISTINCXSB.MajorFROMXSB;
1 SELECT语句语法格式 结果集中可以包含重复行 结果集中只能包含唯一行 SELECT[ALL|DISTINCT] 从基本结果集中返回额外的行 [TOP(expression)[PERCENT][WITHTIES]]
2 SELECT语句的处理顺序
1 FROM
2 ON
3 JOIN
4 WHERE
5 GROUPBY
6 WITHCUBE或WITHROLLUP
7 HAVING
8 SELECT
9 DISTINCT 10ORDERBY 11TOP 所有被使用的子句必须按语法说明中显示的顺序严格的排序。
3 SELECT_list语句语法格式
4 1、选择所有列EG:查询PXSCJ数据库中XSB表的所有数据。
SELECT*FROMXSB;
2、选择表中指定的列EG:查询PXSCJ数据库的XSB表中各个同学的姓名、专业和总学分。
SELECTXSB.Stu_ID,XSB.Sname,XSB.TcreditFROMXSB;
3、消除结果集中的重复行EG:查询XSB表中的专业,消除结果集中重复行。
SELECTDISTINCTXSB.MajorFROMXSB;比较:查询XSB表中的专业和性别,消除结果集中重复行。
SELECTDISTINCTXSB.Major,XSB.SsexFROMXSB;
5 4、定义列别名EG:查询XSB表中学生的学号、姓名和总学分,结果中各列的标题分别指定为“学号”、“姓名”和“总学分”。
SELECTXSB.Stu_IDAS学号,XSB.SnameAS姓名,XSB.TcreditAS总学分FROMXSB;
5、限制结果集返回行数EG:查询XSB表中学生的姓名、专业和总学分,返回结果集的前6行。
SELECTTOP
(6)XSB.Sname,XSB.Major,XSB.TcreditFROMXSB;比较:查询XSB表中学生的姓名、专业和总学分,返回结果集的前6%行。
SELECTTOP
(6)PERCENTXSB.Sname,XSB.Major,XSB.TcreditFROMXSB;
6 6、替换查询结果中的数据EG:查询XSB表中学生的学号、姓名和总学分,对总学分按以下规则替换:若总学分为空值,则替换为“尚未选课”;若总学分小于50,则替换为“不合格”;若总学分在50与52之间,则替换为“合格”;若总学分大于52,则替换为“优秀”。
列标题更改为“等级”。
SELECTXSB.Stu_ID,XSB.Sname,等级=CASEWHENXSB.TcreditISNULLTHEN'尚未选课'WHENXSB.Tcredit<50THEN'不合格'WHENXSB.Tcredit>=50andXSB.Tcredit<=52THEN'合格'ELSE'优秀'ENDFROMXSB;
7 7、计算列值EG:按150分计算成绩并查询学生的成绩情况。
SELECTCJB.Stu_ID,CJB.C_ID,成绩=CJB.Grade*1.5FROMCJB;比较:SELECTCJB.Stu_ID,CJB.C_ID,CJB.Grade=CJB.Grade*1.5 FROMCJB;
8、聚合函数
(1)SUM和AVGSUM/AVG([ALL|DISTINCT]expression)SUM/AVG在计算时,忽略NULL值。
8 EG:求学号为081101的学生所学课程的平均成绩和总成绩。
SELECTAVG(CJB.Grade)AS平均成绩,SUM(CJB.Grade)AS总成绩FROMCJBWHERECJB.Stu_ID='081101';
(2)MAX和MINMAX/MIN([ALL|DISTINCT]expression)MAX/MIN在计算时,忽略NULL值。
EG:求选修101课程的学生的最高分和最低分。
SELECTMAX(CJB.Grade)AS最高分,MIN(CJB.Grade)AS最低分FROMCJBWHERECJB.C_ID='101';
9
(3)COUNTCOUNT{([ALL|DISTINCT]expression)|*}COUNT在计算时,忽略NULL值;COUNT(*)返回总数目,包含空值。
EG:求学生的总数。
SELECTCOUNT(*)FROMXSB; EG:统计备注不为空的学生数。
SELECTCOUNT(XSB.Remark)FROMXSB; EG:求选修了课程的学生总数。
SELECTCOUNT(DISTINCTCJB.Stu_ID)FROMCJB; 10 WHERE子句语法格式 [WHERE
11 WHERE子句语法格式
=|>|>=|!
>|<|<=|!
<}expression /*比较运算*/ |string_expression[NOT]LIKEstring_expression[ESCAPE'escape_character']/*字符串模式匹配*/ |expression[NOT]BETWEENexpressionANDexpression /*指定范围*/ |expressionIS[NOT]NULL搜索指定的单词、短语等 /*是否空值判断*/ |CONTAINS({column|*},'
=|>|>=|!
>|<|<=|!
<}{ALL|SOME|ANY}(subquery) /*比较子查询*/ |EXISTS(subquery)}/*EXIST子查询*/ 12
1、表达式比较 {expression{=|<>|!
=|>|>=|!
>|<|<=|!
<}expression /*比较运算*/ EG:查询PXSCJ数据库XSB表中学号为081101的同学的情况。
SELECTXSB.*FROMXSBWHEREXSB.Stu_ID='081101'; EG:查询XSB表中总学分大于50的同学的情况。
SELECTXSB.*FROMXSBWHEREXSB.Tcredit>50; EG:查询XSB表中通信工程专业总学分大于等于52的同学的情况。
SELECTXSB.*FROMXSBWHEREXSB.Major='通信工程'ANDXSB.Tcredit>=52; 13
2、模式匹配 string_expression[NOT]LIKEstring_expression[ESCAPE'escape_character']/*字符串模式匹配*/ 字符串和通配符 允许在字符串中搜索通配符 通配符列表 通配符 说明 示例 包含零个或多个字符的任WHEREtitleLIKE'puter%' % 意字符串。
将查找在书名中任意位置包含单词puter"的所有书名。
_(下划线)任何单个字符。
WHEREau_fnameLIKE'_ean'将查找以ean结尾的所有4个字母的名字(Dean、Sean等)。
WHEREau_lnameLIKE'[C-P]arsen' 指定范围([a-f])或集合 将查找以arsen结尾并且以介于C与P之间的任何单个字符开始的作者姓氏, [] ([abcdef])中的任何单个字 例如Carsen、Larsen、Karsen等。
在范围搜索中,范围包含的字符可能因排 符。
序规则的排序规则而异。
不属于指定范围([a-f])或 WHEREau_lnameLIKE'de[^l]%' [^] 集合([abcdef])的任何单个 将查找以de开始并且其后的字母不为l的所有作者的姓氏。
字符。
14 EG:查询PXSCJ数据库XSB表中姓“王”且单名的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SnameLIKE'王_'; EG:查询XSB表中学号倒数第3个数字为
1,且倒数第1个数在1~5之间的学生的学号、姓名和专业。
SELECTXSB.Stu_ID,XSB.Sname,XSB.MajorFROMXSBWHEREXSB.Stu_IDLIKE'%1_[12345]'; EG:查询XSB表中名字包含%的学生学号和姓名。
SELECTXSB.Stu_ID,XSB.SnameFROMXSBWHEREXSB.SnameLIKE'%#%%'ESCAPE'#'; 定义转义字符 15 比较: EG:查询PXSCJ数据库XSB表中姓“王”且全名为3个汉字的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SnameLIKE'王__'; EG:查询PXSCJ数据库XSB表中姓“王”且全名为3个汉字的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SnameLIKE'王%‘andlen(Sname)=3;; 16
3、范围比较 |expression[NOT]BETWEENexpressionANDexpression/*指定范围*/ expression[NOT]IN(subquery|expression[,...n]) /*IN子句*/ EG:查询PXSCJ数据库XSB表中不在1989年出生的学生的情况。
SELECTXSB.*FROMXSBWHEREXSB.SdateNOTBETWEEN'1989-1-1'AND'1989-12-31'; EG:查询XSB表中专业为“计算机”、“通信工程”或“无线电”的学生情况。
SELECTXSB.*FROMXSBWHEREXSB.MajorIN('计算机','通信工程','无线电'); 17
4、空值比较|expressionIS[NOT]NULL /*是否空值判断*/ 不使用NOT时,若表达式expression的值为空值,则返回TRUE,否则返回FALSE;使用NOT时,结果相反。
EG:查询PXSCJ数据库XSB表中总学分尚不定的学生情况。
SELECTXSB.*FROMXSBWHEREXSB.TcreditISNULL; 18
5、子查询 子查询除了可以用在SELECT语句中,也可以用在INSERT、UPDATE和DELETE语句中。
通常与IN、EXIST谓词及比较运算符结合使用。
(1)IN子查询 |expression[NOT]IN(subquery) /*IN子句*/ 用于进行一个给定值是否在子查询结果集中的判断。
当表达式expression与子 查询subquery的结果表中的某个值相等时,IN谓词返回TRUE,否则返回 FALSE;使用了NOT,则相反。
EG:查询选修了课程号为206的课程的学生基本情况。
SELECT
XSB.*FROMXSBWHEREXSB.Stu_IDIN(SELECTCJB.Stu_IDFROMCJB 系统先执行子查询,产生一个结果表,再执行查询。
WHERECJB.C_ID='206');19 EG:查询未选修离散数学的学生情况。
SELECTXSB.*FROMXSB WHEREXSB.Stu_IDNOTIN ( SELECTCJB.Stu_ID FROMCJB WHERECJB.C_IDIN ( SELECTKCB.C_ID FROMKCB WHEREKCB.Cname='离散数学' ) ); 20
(2)比较子查询expression{=|<>|!
=|>|>=|!
>|<|<=|!
<}{ALL|SOME|ANY}(subquery) /*比较子查询*/ ALL:指定表达式要与子查询结果集中的每个值都进行比较,满足时返回TRUE,否则返回FALSE; SOME或ANY:表达式只要与子查询结果集中的某个值满足比较的关系,就返回TRUE,否则返回FALSE。
EG:查询选修了离散数学的学生学号。
SELECTCJB.Stu_IDFROMCJBWHERECJB.C_IDIN (SELECTKCB.C_IDFROMKCB 可否将IN改为“=”? WHEREKCB.Cname='离散数学'); 21 EG:查找比所有计算机系的学生年龄都大的学生。
SELECTXSB.*FROMXSBWHEREXSB.Sdate
由EXISTS引入的子查询的选择列表通常几乎都是由星号(*)组成。
由于只是 测试是否存在符合子查询中指定条件的行,因此不必列出列名。
EG:查询选修了206号课程的学生姓名。
SELECTXSB.SnameFROMXSBWHEREEXISTS (SELECTCJB.*FROMCJB WHERECJB.Stu_ID=XSB.Stu_IDANDCJB.C_ID='206'); 处理过程:①查找外层查询中XSB表的第一行,根据学号值处理内层查询;②若结果不为空,则取出该行姓名值作为结果集的一行③依次查找外层查询的2、3、4……行,直至XSB中所有行查找完为止。
24 EG:查询没有选修206号课程的学生姓名。
SELECTXSB.SnameFROMXSBWHERENOTEXISTS(SELECTCJB.*FROMCJBWHERECJB.Stu_ID=XSB.Stu_IDANDCJB.C_ID='206'); 比较: SELECTXSB.SnameFROMXSBWHEREXSB.Stu_IDNOTIN(SELECTCJB.Stu_IDFROMCJBWHERECJB.C_ID='206'); SELECTXSB.SnameFROMXSBWHEREXSB.Stu_ID<>(SELECTCJB.Stu_IDFROMCJBWHERECJB.C_ID='206'); 25 EG:查询选修了全部课程的学生姓名。
(没有一门课程是他不选修的。
)SELECTXSB.SnameFROMXSBWHERENOTEXISTS( SELECT*FROMKCBWHERENOTEXISTS (SELECT*FROMCJBWHERECJB.Stu_ID=XSB.Stu_IDANDCJB.C_ID=KCB.C_ID )); 26 SELECT关键字后面也可以定义子查询。
EG:从XSB表中查找所有女生的姓名、学号及其与081101号学生的年龄差距。
SELECTXSB.Sname,XSB.Stu_ID,YEAR(XSB.Sdate)-YEAR((SELECTXSB.SdateFROMXSBWHEREXSB.Stu_ID='081101'))AS年龄差距FROMXSBWHEREXSB.Ssex=0; 27 ANY(或SOME)、ALL谓词与聚集函数、IN谓词的转换 ANYALL = <>或!
= < <= > >= IN ----
28 FROM子句语法格式 [FROM{
EG:从KCB表中查找101号课程的开课学期。
SELECTKCB.TermFROMKCBWHEREKCB.C_ID='101'; EG:查找081101号学生计算机基础课的成绩。
SELECTCJB.GradeFROMCJB,KCBWHERECJB.Stu_ID='081101'ANDKCB.Cname='计算机基础'AND KCB.C_ID=CJB.C_ID; 30 EG:查询选修了学号为081102的同学所选修的全部课程的学生的学号。
(081102学生选修的课程没有一门是他不选修的。
)SELECTDISTINCTCJ1.Stu_IDFROMCJBASCJ1WHERENOTEXISTS( SELECT*FROMCJBASCJ2WHERECJ2.Stu_ID='081102'ANDNOTEXISTS (SELECT*FROMCJBASCJ3WHERECJ3.Stu_ID=CJ1.Stu_IDANDCJ3.C_ID=CJ2.C_ID )); 31 2、derived_table[AS]table_alias[(column_alias[,...n])] /*子查询*/ 子查询可以在FROM子句中使用,derived_table表示执行子查询返回的表,必须使用AS关键字为子查询产生的表定义一个别名。
EG:从XSB表中查找总学分大于50的男生的姓名和学号。
SELECTSTUDENT.Stu_ID,STUDENT.SnameFROM(SELECTXSB.*FROMXSBWHEREXSB.Tcredit>50)ASSTUDENTWHERESTUDENT.Ssex=1;SELECTXSB.Stu_ID,XSB.SnameFROMXSBWHEREXSB.Tcredit>50ANDXSB.Ssex=1; SELECTXSB.Stu_ID,XSBT.SnameFROM(SELECTXSB.*FROMXSBWHEREXSB.Tcredit>50)ASSTUDENTWHEREXSB.Ssex=1;32 EG:在XSB表中查找1990年1月1日以前出生的学生的姓名和专业,分别使用name和speciality表示。
SELECTm.name,m.specialityFROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101')ASm(num,name,sex,birthday,speciality,score,mem);SELECTm.Snamename,m.MajorspecialityFROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101')ASm; SELECTm.SnameASname,m.MajorASspecialityFROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101')ASm; SELECTm.name,m.speciality FROM(SELECTXSB.*FROMXSBWHEREXSB.Sdate<'19900101') ASm(name,speciality); 33 连接查询(涉及多个表的查询) 在T-SQL中,连接查询有两大表示形式:符合SQL标准的连接谓词表示形式;T-SQL扩展的,使用JOIN关键字的表示形式。
1、连接谓词在SELECT语句的WHERE子句中使用比较运算符给出连接条件对表进行连接。
EG:查找PXSCJ数据库每个学生的基本情况以及选修的课程情况。
SELECTXSB.*,CJB.*FROMXSB,CJBWHEREXSB.Stu_ID=CJB.Stu_ID;比较: SELECTXSB.*,CJB.C_ID,CJB.GradeFROMXSB,CJBWHEREXSB.Stu_ID=CJB.Stu_ID; 34 EG:查找选修了206号课程且成绩在80分以上的学生姓名及成绩。
SELECTXSB.Sname,CJB.GradeFROMXSB,CJBWHEREXSB.Stu_ID=CJB.Stu_IDANDCJB.C_ID='206'ANDCJB.Grade>=80; EG:查找选修了“计算机基础”课程且成绩在80分以上的学生学号、姓名、课程名及成绩。
SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSB,KCB,CJBWHEREXSB.Stu_ID=CJB.Stu_IDANDKCB.C_ID=CJB.C_IDANDKCB.Cname='计算机基础'ANDCJB.Grade>=80; 35 连接查询和子查询的区别:连接查询可以合并两个或多个表中的数据;带子查询的SELECT语句的结果只能来自一个表。
36
2、以JOIN关键字指定的连接
(1)内连接(INNERJOIN)EG:查找PXSCJ数据库每个学生的基本情况以及选修的课程情况。
SELECT*FROMXSBINNERJOINCJBONXSB.Stu_ID=CJB.Stu_ID; SELECT*FROMXSBJOINCJBONXSB.Stu_ID=CJB.Stu_ID; 执行结果将包含XSB表和CJB表的所有字段(不去除重复字段)。
38 EG:查询选修了206号课程且成绩在80分以上的学生姓名和成绩。
SELECTXSB.Sname,CJB.GradeFROMXSBJOINCJBONXSB.Stu_ID=CJB.Stu_IDWHERECJB.C_ID='206'ANDCJB.Grade>=80; EG:查找不同课程成绩相同的学生的学号、课程号和成绩。
(自连接)SELECTa.Stu_ID,a.C_ID,b.C_ID,a.GradeFROMCJBaJOINCJBbONa.Grade=b.GradeANDa.Stu_ID=b.Stu_IDAND a.C_ID!
=b.C_ID; 39 EG:查找选修了“计算机基础”课程且成绩在80分以上的学生学号、姓名、课程名和成绩。
SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSBJOINCJBJOINKCBONCJB.C_ID=KCB.C_IDONXSB.Stu_ID=CJB.Stu_IDWHEREKCB.Cname='计算机基础'ANDCJB.Grade>=80; SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSBJOINCJBONXSB.Stu_ID=CJB.Stu_IDJOINKCBONCJB.C_ID=KCB.C_IDWHEREKCB.Cname='计算机基础'ANDCJB.Grade>=80; SELECTXSB.Stu_ID,XSB.Sname,KCB.Cname,CJB.GradeFROMXSBJOINCJBJOINKCBONXSB.Stu_ID=CJB.Stu_IDONCJB.C_ID=KCB.C_IDWHEREKCB.Cname='计算机基础'ANDCJB.Grade>=80; 40
(2)外连接(OUTERJOIN)外连接的结果表不但包含满足连接条件的行,还包括相应表中的所有行。
左外连接(LEFTOUTERJOIN):结果表中除了包括满足连接条件的行外,还包括左表的所有行;右外连接(RIGHTOUTERJOIN):结果表中除了包括满足连接条件的行外,还包括右表的所有行;完全外连接(FULLOUTERJOIN):结果表中除了包括满足连接条件的行外,还包括两个表的所有行;其中OUTER关键字可以省略。
41 EG:查找所有学生情况,以及他们选修的课程号,若学生未选修任何课,也要包括其情况。
SELECTXSB.*,CJB.C_IDFROMXSBLEFTJOINCJBONXSB.Stu_ID=CJB.Stu_ID; SELECTXSB.*,CJB.C_IDFROMCJBRIGHTJOINXSBONXSB.Stu_ID=CJB.Stu_ID;EG:查找被选修了的课程的选修情况和所有开设的课程名。
SELECTCJB.*,KCB.CnameFROMCJBRIGHTJOINKCBONCJB.C_ID=KCB.C_ID; SELECTCJB.*,KCB.CnameFROMKCBLEFTJOINCJBONCJB.C_ID=KCB.C_ID; 42
(3)交叉连接(CROSSJOIN)将两个表进行笛卡尔积运算,结果表由第一个表的每一行与第二个表的每一行拼接后形成的表。
EG:列出学生所有可能的选课情况。
SELECTXSB.Stu_ID,XSB.Sname,KCB.C_ID,KCB.CnameFROMXSBCROSSJOINKCB; EG:列出软件工程学生所有可能的选课情况。
SELECTXSB.Stu_ID,XSB.Sname,KCB.C_ID,KCB.CnameFROMXSBCROSSJOINKCBWHEREXSB.Major='软件工程'; 43 GROUPBY子句语法格式 [GROUPBYgroup_by_expression]/*GROUPBY子句,指定分组表达式*/ GROUPBY子句具有符合ISO的语法和不符合ISO的语法。
在一条SELECT语句中只能使用一种语法样式。
对于所有的新工作,请使用符合ISO的语法。
提供不符合ISO的语法的目的是为了实现向后兼容。
1、非ISO标准的GOURPBY子句 分组表达式 [GROUPBY[ALL]group_by_expression[,...n] [WITH{CUBE|ROLLUP}]] 指定CUBE、ROLLUP操作 指定结果集内不仅包含由GROUPBY提供的行,同时还包含汇总行。
44 EG:输出PXSCJ数据库中各专业名。
SELECTXSB.MajorFROMXSBGROUPBYXSB.Major; 比较:SELECTXSB.MajorFROMXSB; SELECTDISTINCXSB.MajorFROMXSB;
声明:
该资讯来自于互联网网友发布,如有侵犯您的权益请联系我们。