登陆注册
31848700000011

第11章 Oracle数据库基础——SQL语言(6)

5.4.1.5 对查询结果分组

默认情况下,表中所有的行作为一个组处理。在SELECT语句中可以使用GROUP BY子句将行划分成较小的组。然后,使用聚组函数返回每一个组的汇总信息。另外,可以使用HAVING 子句限制返回的结果集。

GROUP BY子句可以将查询结果的各行按一列或多列取值相等的原则进行分组,值相等的为一组。如果未对查询结果分组,聚组函数将作用于整个查询结果,即整个查询结果只有一个函数值。否则,聚组函数将作用于每一个组,即每一组都有一个函数值。

例5-88 查询各个课程号与相应的选课人数。

SQL>SELECT cno,count(Sno)

FROM sc

GROUP BY cno;

该SELECT语句对sc表按cno的取值进行分组,所有具有相同cno值的元组为一组,然后对每一组作用聚组函数COUNT以求得该组的学生人数。

如果分组后还要求按一定条件对这些组进行选择,最终只输出满足条件的组,则可以使用HAVING子句指定选择条件。

例5-89 查询选修4门以上课程的学生的学号。

SQL>SELECT sno

FROM sc

GROUP BY sno

HAVING COUNT(*)>4;

使用GROUP BY和HAVING子句时要注意以下几个问题。

①带有GROUP BY 子句的查询语句中,在SELECT子句中指定的列要么是GROUP BY子句中指定的列,要么包含聚组函数,否则出错。

例5-90 没有包含GROUP BY子句的SELECT语句。

SQL>SELECT ename,sum(sal)FROM emp

语句执行时出错。改成下列语句则就是正确的:

SQL>SELECT ename,sum(sal)FROM emp

GROUP BY ename;

但在GROUP BY 子句中的列不一定非在SELECT子句中出现。

例5-91 按JOB分组,查询每一类JOB的最大工资。

SQL>SELECT max(sal)FROM emp

GROUP BY job

②可以使用多个列进行分组。

例5-92 查询每个部门的每种职位的雇员数。

SQL>SELECT deptno,job,count(*)

FROM emp

GROUP BY deptno,job

③查询语句的SELECT和ORDER BY、HAVING子句,是聚组函数唯一可以出现的地方。在WHERE子句中不能使用聚组函数。

例5-93 使用聚组函数的WHERE子句。

SQL>SELECT deptno,avg(sal)FROM emp

WHERE avg(sal)>2000

GROUP BY deptno;

语句执行后出现一个错误。正确的做法是在数据库中将所有行分组,然后使用HAVING子句限制这些分组行的输出如例。

例5-94 输出总工资大于8500的部门及部门的总工资。

SQL>SELECT deptno,sum(sal)

FROM emp

WHERE sal>1000

GROUP BY detpno

HAVING sum(sal)>8500

ORDER BY deptno

当在GROUP BY子句中使用HAVING子句时,查询结果中只返回满足HAVING条件的组。在一个SELECT语句中可以有WHERE子句和HAVING子句,均用于设置限定条件。HAVING子句与WHERE子句的区别如下。

WHERE子句的作用是在对查询结果进行分组前,将不符合WHERE条件的行去掉。即在分组之前过滤数据。WHERE条件中不能包含聚组函数。使用WHERE条件选择满足条件的行。

HAVING子句的作用是筛选满足条件的组,即在分组之后过滤数据。HAVING条件中经常包含聚组函数。使用HAVING条件选择满足条件的组。使用HAVING子句时必须首先使用GROUP BY进行分组。

5.4.1.6 SELECT 语句中的表达式

SQL命令中可以使用加、减、乘、除算术运算符构成表达式:在SELECT语句的各个子句中,除了FROM子句中不能使用表达式以外,其他任何子句都可以使用表达式,在一条查询语句中可多处使用表达式。

例5-95 查询奖金高于其工资的5%的雇员信息。

SQL>SELECT ename,sal,comm,comm/sal FROM emp

WHERE comm>0.05*sal

ORDER BY comm/sal DESC

表达式可以嵌套,算术运算符有自己的优先级。

5.4.1.7 START WITH和CONNECT BY子句

如果表中包含具有层次结构的数据,则可以使用该子句按照层次顺序显示查询结果。例如:emp表中的雇员编号(empno)和经理号(mgr)两列,反映出雇员之间领导与被领导的关系,这种关系就是一种树结构。

父节点的empno与子节点的MGR相同。树结构中,有且仅有一个节点无父节点中的KING,该节点为根节点。除根节点外,任何节点均有并且只能有一个父节点,有一个、多个或没有子节点。

START WITH子句确定层次查询开始的根行,根行必须满足该子句的WHERE条件。CONNECT BY子句指定层次中父行和子行之间的关系。

5.4.2 联结查询

简单查询只针对一个表进行的,实际应用时往往涉及多个表,这就需要对多个表进行联结。若一个查询同时涉及两个以上的表,则称为联结查询。联结查询包括等值联结、非等值联结、自然联结、自联结、外联结和复合条件联结等。这就是关系代数中的联结运算。

为了从多张表中查询数据,必须识别联结多张表的公共列。在WHERE子句中,列名前面由表名加以限制,以免产生二义性。

注意:一旦定义了表的别名,应该用表的别名去限制列名。别名应该尽量简短,有意义。

例5-97 从emp和dept表中查询奖金不空的雇员的部门号、部门地点、姓名、工资。

SQL>SELECT dname department,d·loc location,e·ename name,e·sal

FROM dept d,emp e

WHERE d·deptnoe·deptno

AND comm IS NOT NULL;

为了将多张联结在一起,最少的联结条件的个数是表数减1,即n 个表之间的联结至少有n-1个联结条件。在联结查询的WHERE 子句中除了联结条件以外,也可以包含其他条件,用AND运算符联结其他条件和联结条件。

5.4.2.1 等值联结

在上述联结条件中的比较运算符如果是“”号,则称为等值联结,否则称为非等值联结。

例5-98 查询每个学生及其选修课程的情况。

SELECT student.*,sc.*

FROM student,sc

WHERE student.snosc.sno;

为了避免混淆,在查询语句中用到各个表中都有的属性名时前面加上表名,没有重复的属性名不必在前面加表名。查询结果如下:

st udent.sno sname *** age dept sc.sno cno grade

98001 吴晨 男19 CS 98001 C2 87

5.4.2.2 自然联结

如果是按照两个表中的相同属性进行等值联结,且结果中去掉了重复的属性列,但保留了所有不重复的属性列,则称之为自然联结。

例5-99 用自然联结查询每个学生及其选修课程的情况。

SELECT student.sno,sname,***,age,dept,cno,grade

FROM student,sc

WHERE student.snosc.sno;

等值联结与自然联结的差别如下。

等值联结的联结条件中属性名1与属性名2可以不同名,但必须有相同的数据类型和值域。

等值联结的结果是不去掉重复属性,而自然联结的结果中去掉重复属性。

5.4.2.3 复合联结

上面联结查询中,WHERE子句中只有一个条件,即用于联结两个表的联结条件。WHERE子句中除了联结条件外,还可以有多个限制条件。联结条件用于多个表之间的联结,限制条件限制取的记录要满足什么条件。这种联结操作,称为复合联结。

例5-100 查询选修C2号课程且成绩在90分以上的所有学生的学号和姓名。

SELECT student.sno,sname

FROM student,sc

WHERE student.snosc.sno(联结条件)

AND sc.cno′C2′AND sc.grade>90;(限制条件)

5.4.2.4 非等值联结

非等值联结是指联结条件中的运算符不是等号,可以是大于、大于等于、小于、小于等于、不等于运算符,也可以是BETWEEN AND 指定的一个范围。

假设部门和雇员数据库中的emp和SALGRADE表的结构和数据如下:

emp(empno,ename,job,mgr、sal,deptno),其数据如下:

empno ename job mgr sal d eptno

……1001 张三 工程师1002 2500 20

……1002 李四 高级工程师1003 4500 20

salgrade(grade,lowsal,highsal),其数据如下:

gra de l owsal h ighsal

1 800 2000

2 2001 3999

3 4000 5999

4 6000 9000

emp表中含有每一个雇员的编号、姓名、工作、经理编号、工资和部门号,而SALGRADE表中记录每一个等级所对应的最低工资和最高工资。

例5-101 查询工资等级为3的雇员姓名。

SELECT ename

FROM emp,salgrade

WHERE sal BETWEEN lowsal AND highsal(非等值联结条件)

AND grade3(限制条件)

例5-102 查询emp表中的每一雇员的工资的等级。

SQL>SELECT empno,ename,sal,grade

FROM emp e,grade g

WHERE e.sal BETWEEN g.lowsal AND g.hisal

ORDER BY e.sal

5.4.2.5 自联结

如果联结操作是在同一个表的不同记录之间进行,这种联结称为自联结。因为自联结查询仅涉及一张表,所以在FROM子句中该表名出现两次,分别用两个不同的别名表示。两个别名当作两张不同的表进行处理,与其他的表联结一样,也使用一个或多个相关的列联结。为了区分同一张表的不同行的列,在列名前用别名加以限制。

例5-103 查询至少选修了课程号为C2和C4的学生学号。

SELECT x.sno

FROM sc x,sc y

WHERE x.snoy.sno(联结条件)

AND x.cno′C2′(限制条件)

AND y.cno′C4′(限制条件)

例5-104 查询每一个雇员的经理姓名(查询emp表)。

SELECT manager.ename

FROM emp worker,emp manager

WHERE worker.mgrmanager.empno(联结条件)

5.4.2.6 外联结

在通常的联结操作中,只有满足联结条件的元组才能作为结果输出。外联结的查询结果是等值联结查询结果的扩展。外联结不仅返回满足联结条件的所有记录,而且也返回了一个表中的那些在另一个表中没有匹配的行记录。

如果在student表中有某些学生,但这些学生没有选课,则在sc表中没有对应的记录。如果按等值联结,则这些没有选课的学生信息不会输出。如果想以student表为主体列出每个学生的基本情况及其选课情况,若某一学生没有选课,则只输出学生的基本情况信息,其选课信息为空值。此时需要用外联结。

外联结的操作符是(+)。(+)号放在联结条件中信息不完全的那一边(即没有匹配行的那一边)。例如:执行一个外联结,联结A表和B表,假如想返回A表中的所有行,则将外联结运算符(+)放到联结条件的B表的列那一边,此时,对A表中的所有行,如果B表中没有匹配的行,则B表中的列返回NULL。否则,假如想返回B表中的所有行,则将外联结运算符(+)放到联结条件的A表的列那一边,此时,对B表中的所有行,如果A表中没有匹配的行,则A表中的列返回NULL。

例5-105 以student表为主体列出每个学生的基本情况及其选课情况,若某一学生没有选课,只输出学生的基本情况信息,其选课信息为空值。

SQL>SELECT s.sno,sname,***,age,cno,grade

FROM student s,sc

WHERE s.snosc.sno(+)(联结条件)

外联结运算符(+)出现在联结条件右边,称为右外联结;出现在联结条件左边,称为左外联结。

外联结就像运算符(+)所在边的表增加一个“万能”的行,这个行全部由空值组成,可以和另一边的表中所有不满足联结条件的元组进行联结。

同类推荐
  • 网络知识

    网络知识

    一般地说,将分散的多台计算机、终端和外部设备用通信线路互联起来,彼此间实现互相通信,并且计算机的硬件、软件和数据资源大家都可以共同使用,实现资源共享的整个系统就是计算机网络。
  • 信息革命

    信息革命

    随着经济社会的快速发展,电子产品走进了千家万户,与电子产品相伴的信息技术也已渗透到人们生产生活的方方面面。加强信息技术普及,已成为业内人士的共识。鉴于此,在有关部门的大力支持下,经过认真筹划,我们编辑出版了《信息革命》一书。该书以时间为经,在记述信息技术发展历程的同时,深入浅出地介绍了信息技术的相关知识,对人们更好地利用现代信息技术服务经济社会建设和个人生产生活必将产生积极作用。本书由李大东主编。
  • 云计算、网络安全和网络盗窃:网络世界防盗初学指南

    云计算、网络安全和网络盗窃:网络世界防盗初学指南

    网络犯罪层出不穷,保护自己的安全,防止受到攻击,似乎是一个艰巨的任务。幸运的是,有一些人人都能采取的措施,可以降低成为网络袭击对象的风险。保证基于云计算程序的安全和降低被袭击的风险,关键在于理解云安全的共同责任。云提供商需要全力确保实施尽可能严格的安全策略。
热门推荐
  • 赤色火焰

    赤色火焰

    【天谕同人衍生小说】那团火印在她的记忆里挥之不去,那红色出现在他的梦境中难以摆脱。他只是想一心悟道,领悟白帝留下的刃道奥义,命运却再三捉弄。她不明白守护时间秩序有什么意义,可她又不知走向何方。柳夷光、启极、帝都、狐族等,所有的一切交织在云垂大陆,掀起又一阵狂澜。
  • 快穿之崩坏的剧情君

    快穿之崩坏的剧情君

    白洛凭着自己一路摸爬滚打终于成为一个快穿界的大佬,受众多快穿任务者的膜拜敬仰。某日,主神脸部抽搐朝她挤眉弄眼暗送秋波:“小洛洛,你知道我缺点是什么吗?”白洛面无表情:“活太久,闲的。”“。。。。。为什么,小洛洛你不按套路来!”“拒绝被撩骚,求你给品如剩一条内裤吧!““嘤嘤嘤,小洛洛你变坏了我要惩罚你,嘤嘤嘤。”“神特么的嘤嘤嘤。”主神嘴角扯出一抹诡异弧度,眼波流转出一丝算计,眼中含泪,掏出他四十米长的大砍刀:“小洛洛不可以这么调皮哦,我允许你先跑39米。”白洛黑人问号脸?小朋友是否有很多问号。这次来真!?手起刀落,白洛苦逼地被40米的大砍刀劈成了渣渣。于是乎,白洛一招回到解放前,还被发配快穿最苦逼的地方开始了惩罚之旅、、、、、、
  • 涨姿势系列丛书之每天学点哲学常识

    涨姿势系列丛书之每天学点哲学常识

    本书是一本哲学常识精编荟萃,把读者可能感兴趣的、觉得有意思的,然而又零散的哲学常识编辑成册,帮助读者轻松熟悉古今中外哲学的基本常识,从而丰富知识,开阔视野。融知识性、趣味性于一体,具有较高的阅读和收藏价值。
  • 西藏西藏

    西藏西藏

    《西藏,西藏》分为《梦角连营》《珠峰家乡》《路上风铃》《藏源山南》《相约故乡》等五辑,除了《相约故乡》和《路上风铃》的部分作品,大部分作品都是写西藏的。这是熟悉的西藏,也是陌生的西藏,这是军人眼里的西藏,这是诗人笔下的西藏,这个西藏像一首嘹亮的军歌飞扬在西藏,激荡在史映红火热的心里。
  • 混沌绝世

    混沌绝世

    弱肉强食的三千洲,保留着原始部落。一团混沌孕育而诞生的神胎出世了,在三千洲之力洲出现,被一老汉抚养。十数年后,混沌印记觉醒,先天混沌体一路高歌猛进,在追寻武道绝巅的路上,追觅自己的身世……
  • 攻略师父速成法99种

    攻略师父速成法99种

    终于高考完,苏锦锦的假期啊,充斥着游戏的味道。偶然上线收到的萌新徒弟,才一个星期就能单挑难度副本的boss了,你搞我呐。“师父,你看我是不是大佬了。”“不是”“那我怎样才是大佬”“退游吧”苏锦锦真是欲哭无泪,可缘分,就是这么奇怪啊......
  • 圣裔

    圣裔

    “当正义、公平、理想、善良、梦想这些美好的的东西都被践踏的时候,那么我的子孙们,请找回我的黑暗圣经,我将给你们以力量,因为柯累略斯家族的荣光,注定将再次笼罩整个曼迪斯大陆!”柯累略斯王朝开创者杜马·柯累略斯大帝的墓碑上这样写道。“啊呸!”奥古斯特·威廉·冯·柯累略斯每当被人问到对这句话有什么看法的时候,总是回以简单两个字母。“除了位面之间至高的法则以外,又有什么可以畏惧的?”这位从来都是谜一样的人物,在历史的车轮中最后只留下了这样一句话。Ps:我不是一个淫荡的人,但我希望我淫荡起来不是人qq群:20759911
  • 明星趣事

    明星趣事

    这本小说主要有点损明星,大家不要介意!每个明星都是主角,不喜勿喷,谢谢
  • 魔帝绝宠:医女帝妃

    魔帝绝宠:医女帝妃

    她出生于武术世家,喜研医术,在一次意外中偶然穿越,本来安逸生活就此打破。虽是家世显赫的嫡女千金,可受尽欺辱,父亲哥哥的宠爱,让继母姨娘嫉恨,使她被陷害打骂,生不如死,软弱无能。既借用原主身体,那就别怪她心狠手辣,让曾经的绿茶婊,圣母白莲花付出千万倍代价,逆袭成一代毒王妃,受万人敬仰。可一不注意,养了只饿狼“娘子,放心,我会负责的”“滚粗”“真的,我一定会对你负责的哦”“你还不滚”
  • 我的来历大有问题

    我的来历大有问题

    “我可是通天教主的转世。”觉醒了前世记忆的少年心中充满骄傲,准备穿越诸天,证道成圣。“这一世我一定要改变前世悲剧的下场!”话虽这么说,但随着少年在各个世界之间的旅行,越来越不敢肯定自己的看法了。突然出现在灵魂中的自由之光,地魂中蕴含的神秘知识,让少年对于自己的身世产生了些许困惑。“这么说来,我的来历大有问题?”(原本的书被封了,这本是修改过后再次发出来的。)