
开始学习吧~


SELECT基本查询语句的构成及用法
4.1.1. 选择、投影和连接
Oracle是一个关系数据库管理系统,关系数据库建立在关系模型基础之上,具有严格的数学理论基础。关系数据库对数据库的操作包括集合代数的并、差等运算之外,还定义了一组专门的关系运算:选择、投影和连接,关系运算的特点是运算的对象和结果都是表。
1. 选择
选择(SELECTion),简单地说就是通过一定的条件把自己所需要的数据检索出来。选择是单目运算,其运算对象是一个表。该运算的特点是运算的对象和结果都是表。
要在学生情况表中找出学生表中性别为女且平均成绩在80分以上的行形成一个新表
2. 投影
投影(Projection)也是单目运算。投影就是选择表中指定的列,这样在查询结果中只显示指定的数据列,减少了显示的数据量,也可提高查询的性能。
【例2】若在表4.1.1中对“姓名”和“平均成绩”投影
3. 连接
连接(JOIN)是把两个表中的行按照给定的条件进行拼接而形成的新表。
在实际的数据库管理系统中,对表的连接大多是自然连接,所以自然连接也简称为连接。
本书中若不特别指明,名词“连接”均指自然连接,而普通的连接运算则是按条件连接。
4.2.1 数据库查询
PL/SQL的SELECT语句可以实现对表的选择、投影及连接操作,其功能十分强大。SELECT语句,它是PL/SQL的核心。
SELECT语句的基本结构:SELECT语句复杂,主要的子句如下。
SELECT<列> /*指定要选择的列及其限定*/ FROM<表或视图> /*FROM子句,指定表或视图*/ [WHERE<条件表达式>] /*WHERE子句,指定查询条件*/ [GROUP BY<分组表达式>] /*GROUP BY子句,指定分组表达式*/ [HAVING<分组条件表达式>] /*HAVING子句,指定分组统计条件*/ [ORDER BY<排序表达式>[ASC|DESC]] /*ORDER子句,指定排序表达式和顺序*/ |
4.2.2 选择列
选择表中的列组成的结果表,其语法格式为:
SELECT [ALL | DISTINCT]<列名列表> |
其中<列名列表>指出了结果的形式,其主要格式为:
{ * /*选择当前表或视图的所有列*/ |{<表名>|<视图>}.* /*选择指定的表或视图的所有列*/ |{<列名>|<表达式>} [[AS]<列别名>] /*选择指定的列*/ |<列标题>=<列名表达式> /*选择指定列并更改列标题*/ }[,...n] |
1. 选择一个表中指定的列
使用SELECT语句选择一个表中的某些列,各列名之间要以逗号分隔,其语法格式为:
SELECT<列名1>[,<列名2>[,...n]] FROM<表名> [WHERE<条件表达式>] |
其功能是在FROM子句指定的表中检索符合条件的列。
【例5】查询XSCJ数据库的XSB表中各个同学的学号、姓名和总学分。
在SQL Developer 中 myorcl连接的“工作表”窗口中输入如下语句:
SELECT 学号,姓名,总学分 FROM XSB; |
将光标定位到语句第一行,单击“执行”按钮,结果如图4.1.10所示。执行完后“查询结果”选项中将列出所有结果数据。
【例6】查询XSB表中总学分大于50的同学的学号、姓名和总学分。
SELECT 学号,姓名,总学分 FROM XSB; WHERE 总学分>50; |
在SELECT语句指定列的位置上使用*号时,表示选择表的所有列。
【例7】查询XSB表中的所有列。
SELECT * FROM XSB; |
该语句等价于:
SELECT 学号 姓名,性别,出生时间,专业,总学分,备注 FROM XSB; |
执行后将列出XSB表中的所有数据。
2. 计算列值
使用SELECT对列进行查询时,在结果中可以输出对值计算后的值,即SELECT语句可使用表达式作为结果,其格式为:
SELECT<表达式>[,<表达式>] |
3. 修改查询结果中的列标题
如希望查询结果中的某些列或所有列显示时使用自己选择的列标题,可以在列名之后使用AS子句指定一个列别名来替代查询结果的列标题名。
【例8】查询XSB表中计算机专业同学的学号、姓名和总学分,结果中各列的标题分别指定为num、name和score
SELECT 学号 AS num,姓名 AS name, 总学分 AS score FROM XSB WHERE 专业=‘计算机’; |
也可以省略AS关键字,写成:
SELECT 学号num, 姓名name, 总学分score FROM XSB WHERE 专业=‘计算机’; |
4. 消除结果集中的重复行
对表只选择某些列时,可能会出现重复行。例如,若对XSCJ数据库的XSB表只选择专业和总学分,就会出现多行重复的情况。
可以使用DISTINCT关键字消除结果集中的重复行,其格式是:
SELECT DISITINCT<列名>[,<列名>...] |
注意:关键字DISTINCT的含义是对结果集中的重复行只选择一个,保证行的唯一性。
【例9】对XSCF数据库的XSB表只选择专业和总学分,消除结果集中的重复行。
SELECT DISTINCT 专业 AS 专业,总学分 AS 总学分 FROM XSB; |
与DISTINCT相反,当使用关键字ALL时,将保留结果集的所有行。当SELECT语句中不写ALL与DISTINCT时,默认值为ALL。
4.1.3 选择行
在Oracle中,选择行是通过在SELECT语句中使用“*”查询所有列,以及使用WHERE子句指定选择的条件来实现的。
实际上,选择行是选择列的特例,当SELECT语句中为所有列时,即为选择行。WHERE子句必须紧跟FROM子句之后。
其基本格式为:
WHERE<条件表达式> |
其中,<条件表达式>为查询条件。
格式为:
<条件表达式>::= {[NOT]<判定运算>|(<条件表达式>)} [{AND|OR}[NOT]{<判定运算>|(<条件表达式>)}] }[,...n] |
其中,<判定运算>的结果为TRUE、FALSE或UNKNOWN。
经常用到的格式为:
<判定运算>::= { <表达式1>{=|<|<=|>|>=|<>|!=}<表达式2> /*比较运算*/ |<字符串表达式1>[NOT]LIKE<字符串表达式2>[ESCAPE’<转义字符>’] /*字符串模式匹配*/ |<表达式>[NOT]BETWEEN<表达式1>AND<表达式2> /*指定范围*/ |<表达式>IS[NOT]NULL /*是否空值判断*/ |<表达式>[NOT]IN(<子查询>|<表达式>[,...n]) /*IN子句*/ EXIST(<子查询>) /*EXIST子查询*/ } |
在使用字符串和日期数据进行比较时,注意要符合下面一些限制:
(1) 字符串和日期必须使用单引号括起来。
(2) 字符串数据区分大小写。
(3) 日期数据的格式是敏感的,默认的日期格式是DD-MM月-YY,可使用之前的ALTER SESSION语句将默认日期修改为YYYY-MM-DD。
说明:
1. IN关键字既可以指定范围,也可以表示子查询。
2. 在SQL中,返回逻辑值(TRUE或FALSE)的运算符或关键字都可称为谓词。
1. 表达式比较
比较运算用于比较两个表达式值,共有7个,分别是:=(等于)、<(小于)、<=(小于等于)、>=(大于等于)、<>(不等于)、!=(不等于)。
比较运算的格式为:
<表达式1> {= | < | <= | > | >= | <> |!=} <表达式2> |
注意:
当两个表达式均不为空值(NULL)时,比较运算返回逻辑值TRUE(真)或FALSE(假);而当两个表达式中有一个为空值时,比较运算将返回UNKNOWN。
【例10】查询XSB表中通信工程专业总学分大于等于44的同学的情况。
SELECT * FROM XSB WHERE 专业= ‘通信工程’ AND 总学分 >=44; |
2. 模式匹配
LIKE 谓词用于指出一个字符串是否与指定的字符串相匹配,其运算对象可以是char、varchar2和data类型的数据,返回逻辑值TRUE或FALSE。
LIKE谓词表达式的格式为:
<字符串表达式1> [NOT] LIKE<字符串表达式2>[ESCAPE‘<转义字符>’] |
注意:
在使用LIKE时,可以使用两个通配符:“%”和“_”。若使用带“%”通配符的LIKE进行字符串比较,模式字符串中的所有字符都有意义,包括起始或尾随空格。如果只是希望在模糊条件中表示一个字符,那么可以使用“_”通配符,使用NOT LIKE与LIKE的作用相反。
ESCAPE子句可指定转义字符,转义字符必须为单个字符。当模式串中含有与通配符相同的字符时,应通过转义字符指明其为模式串中的一个匹配字符。
【例11】查询XSB表中姓“王”且单名的学生情况。
SELECT * FROM XSB WHERE 姓名LIKE‘王_’; |
3. 范围比较
用于范围比较的关键字有两个:BETWEEN和IN。当要查询和条件是某个值的范围时,可以使用BETWEEN关键字。
BETWEEN关键字指出查询范围,格式为:
<表达式>[NOT] BETWEEN <表达式1> AND <表达式2> |
当不使用NOT时,若表达式的值在表达式1与表达式2之间(包括这两个值),则返回TRUE,否则返回FALSE;使用NOT时,返回值刚好相反。
注意:
表达式1的值不能大于表达式2的值。
【例12】查询XSB表中不在1996年出生的学生情况。
SELECT * FROM XSB WHERE出生时间 NOT BETWEEN TO_DATE(‘19960101’,‘YYYYMMDD’) AND TO_DATE(‘19960101’,‘YYYYMMDD’); |
使用IN关键字指定值表的格式为:
<表达式> IN (<表达式> [,...n]) |
使用IN关键字可以指定一个值表,值表中列出有可能的值,当表达式中的任意一个匹配时,即返回TRUE,否则返回FALSE。
4. 比较空值
当需要判定一个表达式的值是否为空值时,使用IS NULL关键字,格式为:
<>IS [NOT] NULL |
注意:当有使用NOT时,若表达式的值为空值,返回TRUE,否则返回FALSE;当使用NOT时,结果刚好相反。
【例13】查询XSB表中拥有备注意信息的学生情况。
SELECT * FROM XSB WHERE 备注意 IS NOT NULL; |
4.1.4 查询对象
前面介绍SELECT选择表的列和行操作,这里介绍SELECT查询对象(数据源)构成形式。
【例14】查找与151101号同学所选修课程一致的同学的学号。
SELECT DISTINCT学号 FROM CJB 成绩1 WHERE NOT EXISTS (SELECT * FROM CJB 成绩2 WHERE 成绩2.学号=’151101’AND NOT EXISTS (SELECT *FROM CJB 成绩3 WHERE 成绩3.学号=成绩1.学号 AND 成绩3.课程号=成绩2.课程号) ); |
本例指定SELECT语句查询的对象是表
【例15】在XSB表中查找1997年1月1日以前出生的学生的姓名和专业。
SELECT 姓名,专业 FROM (SELECT * FROM XSB WHERE 出生时间< TO_DATE(‘19970101’,‘YYYYMMDD’)); |
SELECT语句查找的对象既可以是由SELECT查询语句执行后返回的表,也可以是视图。
4.2 集函数和分组语句的配合使用
4.2.1 集函数
对表数据进行检索时,经常需要对结果进行汇总或计算。例如在学生成绩数据库中求某门功课的总成绩、统计各分数段的人数等。
1. 统计函数
统计函数用于计算表中数据,返回单个计算结果。下面对常用的几个统计函数加以介绍。
(1) SUM和AVG函数。这两个函数分别用于求表达式中所有值项的总和与平均值,其语法格式为:
SUM/AVG([ALL|DISTINCT]<表达式>) |
其中,表达式还可以是常量、列、函数。SUM和AVG函数只能对数值型数据进行计算。ALL表示对所有值进行运算,DISTINCT表示去除重复值,默认为ALL。SUM/AVG函数计算时忽略NULL值。
【例1】求选修101课程的学生的平均成绩。
SELECT AVG(函数)AS 课程101 平均成绩 FROM CJB WHERE 课程号=‘101’; |
SELECT AVG(函数)AS 课程101 平均成绩 FROM CJB WHERE 课程号=‘101’; |
(2) MAX和MIN函数。MAX和MIN函数分别用于求表达式中所有值项的最大值与最小值其语法格式为:
MAX/MIN([ALL|DISTINCT]<表达式>) |
其中,表达式的数据类型可以是数字、字符和时间日期类型。ALL表示对所有值进行运算,DISTINCT表示除重复值,默认为ALL。MAX/MIN函数计算时忽略NULL值。
【例2】求选修101课程的学生的最高分和最低分。
SELECT MAX(成绩)AS 课程101的最高分,MIN(成绩)AS 课程101的最低分 FROM CJB WHERE课程号=‘101’; |
(3) COUNT函数。COUNT函数用于统计组中满足条件的行数或总行数,其语法格式为:
COUNT({[ALL|DISTINCT]<表达式>}|*) |
其中,ALL表示对所有值运算,DISTINCT表示去除重复值,默认为ALL。选择“*”时将统计总行数。CONUNT函数计算时忽略NULL值。
【例3】学生数统计。
① 求学生的总人数。
SELECT COUNT(*) AS 学生总数 FROM XSB; |
COUNT(*)不需要任何参数。
② 求选修了课程的学生总人数。
SELECT COUNT(DISTINCT 学号) AS 选修了课程的总人数 FROM CJB; |
③ 统计离散数学课程成绩在85分以上的人数。
SELECT COUNT(成绩)AS 离散数学85分以上的人数 FROM CJB WHERE 成绩>=85 AND 课程号= (SELECT 课程号 FROM KCB WHERE 课程叼=‘离散数学’ ); |
4.2.2 分组语句
1. GROUP BY子句
GROUP BY子句用于对表或视图中的数据按字段分组。
GROUP BY子句的语法格式为:
GROUP BY[ALL]<分组表达式>[,...n] |
分组表达式中包含字段名。指定ALL将显示所有组。使用GROUP BY子句后,SELECT子句中的列表中只能包含在GROUP BY中指出的列或在统计函数中指定的列。
【例4】将XSB表中各专业输出。
SELECT 专业 FROM XSB GROUP BY 专业; |
【例5】求XSB表中各专业的学生数。
SELECT 专业,COUNT(*) AS 学生数 FROM XSB GROUP BY 专业; |
【例6】求被选修的各门课程的平均成绩和选修该课程的人数。
SELECT 课程号,AVG(成绩),COUNT(学号)AS 选修人数 FROM CJB GROUP BY 课程号; |
2. HAVING子句
使用HAVING子句和统计函数对数据进行分组后,还可以使用HAVING子句对分组数据进行进一步的筛选。例如查找XSCJ数据库中平均成绩在85分以上的学生,就是在CJB表上按学号分组后筛选出符合平均成绩大于等于85的学生。
HAVING子句的语法格式为:
[HAVING<条件表达式>] |
HAVING子句的查询条件与WHERE子句类型,不同的是HAVING子句可以使用统计函数,而WHERE子句不可以。
【例7】查找XSCJ数据库中平均成绩在85以上的学生的学号和平均成绩。
SELECT 学号,AVG(成绩)AS 平均成绩 FROM CJB GROUP BY学号 HAVING AVG(成绩) >=85; |
注意:
在SELECT语句中,当WHERE、GROUP BY与HAVING子句都被使用时,要注意它们的作用和执行顺序:
1. WHERE用于筛选由FROM指定的数据对象;
2. GROUP BY用于对WHERE的结果进行组;HAVING则是对GROUP BY子句以后的分组数据进行过滤。
【例8】查找选修课程超过两门且成绩都在80分以上的学生的学号。
SELECT 学号 FROM CJB WHERE 成绩 >=80 GROUP BY 学号 HAVING COUNT(*)>2; |
查询将CJB表中成绩大于或等于80的记录按学号分组,对每组记录计数,选出记录数大于2的各组的学号值形成结果表。
【例9】查找通信工程专业平均成绩在85分以上的学生的学号和平均成绩。
SELECT 学号,AVG(成绩)AS 平均成绩 FROM CJB WHERE 学号 IN ( SELECT 学号 FROM XSB WHERE 专业=‘通信工程’ ) GROUP BY 学号 HAVING AVG(成绩)>=85; |
注意:
先执行WHERE查询条件中的子查询,得到通信工程专业所有学生的学号集;然后对CJB中的每条记录,并判断其学号段值是否在前面所求得的学号集中(否,则跳过该记录,继续处理下一条记录;是,则加入WHERE的结果集)。对CJB筛选完后,按学号进行分组,并在各分组记录中选出平均成绩大于等于85的记录形成最后的结果集。
4.2.3 排序
在应用中经常要对查询的结果排序输出,例如学生成绩由高到低排序。在SELECT语句中,使用ORDER BY子句对查询结果进行排序。
ORADER BY子句的语法格式为:
[ORDER BY{<排序表达式>[ASC | DESC]}[,...n]] |
其中排序表达式可以是列名、表达式或一个正整数,当表达式是一个正整数时,表示按表中的该位置上列排序。关键字ASC表示升序排列,DESC表示降序排列,系统默认值为ASC。
【例10】将通信工程专业的学生按出生时间先后排序。
SELECT * FROM XSB WHERE 专业=‘通信工程’ ORDER BY 出生时间; |
【例11】将计算机专业学生的“计算机基础”课程成绩按降序排列。
SELECT 姓名,成绩 FROM XSB,KCB,CJB WHERE XSB.学号=CJB.学号 AND CJB.课程号=KCB.课程号 AND 课程号=‘计算机基础’AND 专业=‘计算机’ ORDER BY 成绩 DESC; |
使用UNION子句可以将两个或多个SELECT查询结果合并成一个结果集,其语法格式为:
<SELECT 查询语句1> UNION [ALL] <SELECT 查询语句2> [UNION [ALL] <SELECT 查询语句3>[,...n]] |
使用UNION组合两个查询的结果集的两条基本规则如下。
(1) 所有查询中的列数和列的顺序必须相同。
(2) 数据类型必须兼容
说明:
关键字ALL表示合并的结果中包括所有行,不去除重复行。不使用ALL则在合并的结果中去除重复行。含有UNION的SELECT查询也称为联合查询。
【例12】查找总学分>50及学号>151218的学生信息。
SELECT * FROM XSB WHERE 总学分>50 UNION SELECT * FORM XSB WHERE 学号>‘151218’; |
UNION操作常用于归并数据,例如归并月报表形成年报表、归并各部门数据等。UNION还可以与GROUP BY及ORDER BY一起使用,用来对合并所得的结果进行分组或排序。
课后总结
1. 使用DISTINCT关键字消除结果集中的重复行。
2. WHERE子句必须紧跟FROM子句之后。
3. 当要查询的条件是某个值的范围时,可以使用BETWEEN关键字。
4. 使用IN关键字可以指定一个值表,值表中列出所有可能的值。
5. EXISTS谓词用于测试子查询的结果是否为空表。
6. 自然连接查询,无重复列。
7. 内连接按照ON所指定的连接条件合并两个表,返回满足条件的行。
8. 外连接的结果表不但包含满足连接条件的行,还包括相应表中的所有行。外连接包括:左外连接、右外连接、完全外连接。
9. 交叉连接。交叉连接实际上是将两个表进行笛卡儿积运算,结果表是由第1个表的每一行与第2个表的每一行拼接后形成的表,因此其行数等于两表行数之积。

学到了吗?有收获吗?
欢迎大家留言噢~
记得置顶公众号或设为星标
第一时间浏览精彩内容噢~





