瑞星卡卡安全论坛技术交流区系统软件 【推荐】SQL 21 日自学通-1

1234   1  /  4  页   跳转

【推荐】SQL 21 日自学通-1

【推荐】SQL 21 日自学通-1

第一周概貌
从这里开始
在本周我们将向大家介绍SQL 的发展历程及其前景并来学习第一个SQL 语句— —
SELECT 语句它使我们能够用自己的方法来从数据库中检索到自己想要的数据同时
在第一周我们也将学习SQL 的函数联合查询及子查询嵌于查询中的查询并举出多
个例子以帮助您理解它们这些例子是适用于Oracle7 Sybase SQL Server Microsoft
Access Microsoft Query 我们会用高亮显示指出它们的相似之处以及不同点读者们会
觉得这些例子更具有适用性和趣味性
最后编辑2006-02-11 18:20:30
分享到:
gototop
 

第一天SQL 简介
SQL 简史
SQL 的诞生于IBM 公司在加利福尼亚San Jose 的试验室中在七十年代SQL 由这里
开发出来最初它们被称为结构化查询语言Structured Query Language 并常常简称为
sequel 开始时它们是为IBM 公司的DB2 系列数据管理系统RDBMS — — 关系型数据库
管理系统而开发的您在今天仍可以买到在不同平台下运行的该系统事实上是SQL
造就了RDBMS 它是一种非过程语言与第三代过程语言如C 和COBOL 产生于同一时

注非过程性语言的意思就是指与具体过程无关举例来说SQL 描述了如何对数据
进行检索插入删除但它并不说明如何进行这样的操作
这种特性将RDBMS 从DBMS 中区别开来RDBMS 提供了一整套的针对数据库的语
言而且对于大多数的RDBMS 来说这一整套的数据语言就是SQL 这里一整套的意思
就是对数据和处理操作语言是一些过程的集合
有两个标准化组织美国国家标准协会ANSI 和国际标准组织ISO 正致力于SQL
在工业领域的标准化应用工作本书使用的标准为ANSI-92 尽管该标准要求所有的数据
库设计者应遵守这一标准然而所有的数据库系统所用的SQL 均与ANSI-92 存在一定的
差异此外大多数数据库系统对SQL 进行了有针对性的扩展使它们成为了过程型语言
在本书中我们对不同的RDBMS 系统给出了它们的SQL 语言例句希望你能从中发现它们
的共性我们将要讨论的过程型SQL 有PL/SQL 和Transact-SQL 它们将在第18 天和第
19 天提到
数据库简史
对数据库的发展历程有一个简要的了解可以使您更清楚如何使用SQL 来工作数据库
系统在商业领域应用极为广泛大到航空机票售票系统小到孩子们的棒球卡管理系统
数据库将按照我们的意愿来存储和处理这些数据直到最近几年以前大型的数据库系统
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 20
仍只能在大型机上运行而大型机的运行维护使用费用均是非常昂贵的然而在今天
工作站的能力强大到可以让编程人员以极快的速度和极低的价格来设计和发布软件
Dr. Codd's 对关系型数据库系统的十二条规则
关系型数据库是最为流行的数据存储模式它产生于一个名称为A Relational Model of
Data for Large Shared Data Banks 的论文中SQL 进而发展为关系型的数据库对于关系
型数据库Dr. Codd's 定义了12 条规则使之与其他类型的数据库相区别
0 关系型数据库必须通过关系来实现对数据的完全管理
1 所有在关系型数据库中的信息均可以在表中以数值的形式加以体现
2 在关系型数据库中的每一项数据均可以通过库名键名和列名来准确指定
3 关系型数据库系统必须对空值未知的和违规的数据提供系统级的支持有独特
的缺省值而且具有独立域{这一段不太清楚}
4 活动的即时的数据联合— — 它的意思就是在数据库中的数据应有逻辑表格的行的
形式来表达并且可以通过数据处理语言来访问
5 完善的数据子语句— — 它应该至少支持一种有严格语法规则和功能完善的语言并
且应该支持数据和定义处理完整性权限以及事务等操作
6 查看更新规则— — 所有在理论上可以更新的视图可以通过系统操作来更新
7 数据库中数据和插入更新与删除操作— — 该数据库系统不仅要支持数据行的访
问还要支持数据和的插入更新和删除操作
8 数据和物理独立性— — 当数据在物理存储结构上发生变化时应用程序在逻辑上不应
受到影响
9 数据的逻辑独立性— — 当改变表的结构时应用程序在最大程度上不受影响
10 有效性独立— — 数据库的语言必须有定义数据完整性规则的能力数据应即时存
储在线目录而且在处理时必须通过这一五一节
11 发布的独立性— — 当数据第一次发布或当它重新发布时应用程序应不受影响
12 任何程序不可能使用更低级的语言从而绕过数据库语言的有效性规则定义
大多数数据库具有父/子关系这就是说在父结点中保存有子结点的文件指针见下

SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 21
这种方式有优点也有缺点它的好处在于它使得数据在磁盘上的物理存储结构变得不
再重要编程人员只需存储下一个文件的指针就可以实现对下一个文件的访问而且数据
的添加和删除操作也变得非常容易可是不同组的信息想要联合为一个新组就变得困难了
这是因为在这种方式下数据在磁盘上的存储格式不能在数据库建立以后再强制性地改变
如果需要这样做那就必须重新建立一个数据库结构
Codd's 的关系型数据库思想借用的逻辑代数的思想使得数据的子集与父级之间具有
平等的地位
由于信息可以很自然地组织在不同的表格中Dr. Codd 也以这种方式来组织他所提出
的数据库在关系模式下数据被存入类似于表格的结构中这种表格由独立的数据元组
被称为列或字段所组合而成一组数据信息被存储为一行举例来说创建一个包括
雇员内容的关系型数据库我们可以很容易地从雇员表开始而像这样的表在很容易得到
的该表中包含有如下信息姓名年龄职业这三项数据用作雇员表的字段整个表
如下图所示
姓名年龄职业
Will Williams 25 Electrical Engineer
Dave Davidson 34 Museum Curator
Jan Janis 42 Chef
Bill Jackson 19 Student
Don DeMarco 32 Game programmer
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 22
Becky Boudreaux 25 Model
在这个表中有六行记录为了从中找到特定的记录举例来说Dave Davidson 用
户可以望知数据库管理系统在数据库中检索满足条件姓名= Dave Davidson 的记录
如果数据库管理系统已经检索过了全部的数据那么它将会把满足条件的的姓名年龄
职业三项的记录返回给用户SQL 会通知DBMS 找什么样的数据这一检索过程的SQL
例句如下
SELECT * FROM EMPLOYEE
在这里不要刻意去记它的语句我们在明天将会对它进行更为详细的讨论
由于通过明显的关系可以特不同的数据项归结在一起比如雇员的姓名和雇员的年
龄所以关系性数据库管理系统对如何来描述数据之间的关系给出了相当大的弹性通过
精确的的连接和联合运算关系型数据库管理系统可以非常迅速地从不同的表中将所需要
的数据联合见联合运算图然后返回给用户或程序这种联合的特性允许数据库的设计
者将数据信息存储在不同的表中以减少数据的冗余度
右图则反映了相交运算相交运算地意思就是取出两个或多个库所共有的部分
这里有一个简单的例子来显示数据是如何进行逻辑处理的表1-2 是一个被称为报
告的表它的里边有两个字段姓名和工作
Name Duties
Becky Boudreaux Smile
Becky Boudreaux Walk
Bill Jackson Study
Bill Jackson Interview for jobs
在雇员数据库中的年龄和职业字段在每一个记录中均出现重复是不合适的而且随着
时间的进行这些冗余的数据将会占用大量的磁盘空间且使得数据库管理系统在检索数据
表A 表B
联合运算
表A 表B
相交运算
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 23
所耗用的时间增多可是如果你将姓名和工作另存到一个名字叫报告的库中以后
你就可以通过联合操作将报告与雇员通过姓名字段进行联合操作也就是通知RDBMS
将报告与雇员库中姓名与Becky Boudreaux 相同的记录显示出来其结果将如下
所示
Name Age Occupation Duties
Becky Boudreaux 25 Model Smile
Becky Boudreaux 25 Model Walk
关于联合运算的详细讲述将在第6 天的库的联合中讲述
设计数据库的结构
在数据库的设计师已经决定了系统的硬件平台和RDBMS 系统以后余下事情中最为
重要的就是如何来设计数据库的结构了数据库的结构将会影响到是后运行于该库上的应
用程序的性能这个决定数据库的分配情况及联合运算的过程称之为标准化
数据库的前景
电脑技术将对今天世办上的商业产生深远的影响鼠标只要点一下就可以将数据入库
或对其进行访问制造商的国外订货单可以立即接受并执行尽管在20 年以前信息的交换
还需要大型机的支持而办公领域处理事务也仍在采用批处理的方式要完成某一个查询
用户需要将需求提交给服务器上的信息管理系统MIS 给果将会以最快的速度返回给用
户尽管经常不是足够快
此外随着关系型数据库模型的发展有两种技术被引用到了在今天被称为服务器/客
户机的数据库系统当中第一项技术就是个人电脑廉价而又易用的应用程序如Lotus1-2-
3 和WordPerfect 允许员工或家庭用户可以建立文档来快速而准确地处理数据用户也
会经常升级他们的系统以使其速度更快巧的是这时的系统的价格却在迅速下跌
第二项技术则是局域网的发展它导致的世界范围内的办公交叉— — 虽然用户习惯于
采用终端同主机相连在今天一个字处理文档可以存储在本地而被任何连接到网络上的
电脑访问然后苹果的Macintosh 电脑为大家提供了一个友好易用的图形用户界面使得
电脑变得物美价廉此外他们可以访问远程站点并从服务器上下传大量的数据
在这个飞速发展的时期一种新型的叫作服务器/客户机的系统诞生了这种系统的处
理过程被分解上了客户机和数据服务器上新型的应用程序取代了基于主机的应用程序
这一体系有着相当多的优点
l 降低了维护费用
l 减轻的网路负荷处理过程在服务器上和客户机上均有
l 多个操作系统可以基于相同了网络协议来共同工作
l 本地化的数据操作提高了数据的完整性
对于什么是客户机/服务器型电脑系统Bernard H. Boar 的定义如下
客房机/服务器系统就是把单一的任务分解到多个处理器上进行协同处理,就像在单个
处理器上运行时一样一个完备的客户机/服务器系统可以将多个处理器捆绑在一起
以提供一个单一系统虚拟环境共享的资源可以被位于远端的客户机通过特殊的服
务来访问这种结构可以逐级递归所以一级服务器可以在最后转变为客户机进需
要求其他的服务器提供服务就这样一直下去
这种类型的应用程序在设计时需要全新的程序设计技巧今天的用户界面都是图形用
户界面不论是微软的WINDOWS 苹果的MACINTOSH IBM 的OS/2 还是UNIX 的Xwindows
系统均是如此用过使用SQL 和网络应用程序就可以访问位于远端服务器上的
数据库个人电脑处理能力的提高可以对存放在一系统相关的服务器的数据库作出评定
而这此服务器是可以更换的而应用程序则只需做出较少的改动甚至无需改动
交互式语言
本书在许多场合下可以借用BASIC 的概念举例来说Microsoft Access 是基于windows
的单用房应用程序而SQL SEVER 则可以允许100 个用户同时工作SQL 的最大优越性在
于它是一种真正的跨平台的交互式语言由于它可以被程序员在第四代的编程语言中调用
第四代编程语言可以做用少量的代码做大量的工作
易于实现
ORACLE 公司是第一个发行基本于SQL 的关系型数据库管理系统RDBMS 的公司
虽然它是为VAX/VMS 系统开发的ORACLE 公司也是DOS 下的关系型数据库的供应商
之一ORACLE 现在可以运行在近70 种平台之上在八十年代中期Sybase 公司发行了
他们的RDBMS — — SQL Sever 具有客户端数据库访问功能并支持过程存储将在第14 天
的动态应用SQL 中提到和多平台交互工作能力SQL Sever 作为一个成功的产品其客
户机/服务器工作能力是其最为突出的优势所在这个强大的数据库系统具有极高的平台适
应性用C 语言写成的运行于PC 机的ORACLE 其实是运行于VAX 系统上的ORACLE 的
复制
SQL 与客户机/服务器应用程序开发环境
在使用客户机/服务器电脑来开发客户机/服务器应用程序时SQL 和关系型数据库的思
想遍及始终在单用户系统中使用这种技术也可以使您的程序更适应未来的发展
SQL 总览
SQL 是操作和检索关系型数据库的事实上的标准语言它允许程序员和数据库管理员
做如下的工作
l 更改数据库的结构
l 更改系统的安全设置
l 增加用户对数据库或表的许可权限
l 在数据库中检索需要的信息
l 对数据库的信息进行更新
注对于SQL 大家可能还不明白S 即Structured 结构L 即Language 语言这是显
而易见的但是Q 的意思容易让人误解Q 的意思当然是Query 查询— — 如果你
直译的话可是这只限于你对数据库提问但是SQL 能干的不只是查询通过它你可
以建立一个库添加和删除数据对数据作联合当数据库改变时触发动作并把你
的查询存储在程序或数据库中
不幸得很这对于查询来说似乎是一个缺点显然库结构的增加删除修改联
合存储触发以及查询语言在多用户协同工作时有点烦琐我们将会在工作中一直与SQL
打交道不过现在你应该知道它的功能不只是限于它的名字所指的内容了
gototop
 

SELECT 语句是SQL 中应用最多的语句见第二章查询— —SELECT 语句的使用
它会从数据库中检索需要的数据并把结果返回给用户上边的雇员表的举例便是一个典型
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 26
的SELECT 语句的使用例子除了SELECT 语句之外SQL 还提供了用以建立新的数据库
表格字段和索引的语句以及记录的插入和删除语句你将会发现ANSI SQL 还提供了
对核心数据操作的功能许多数据库管理系统还提供了确保数据完整性和强制安全性的工
具见第11 天的传输控制它允许程序员在当前环境不符合的时候强制性地终止语句组
的执行
流行的SQL 开发工具
这一部分将介绍一些大众化的SQL 开发工具每一种工具都有它的优点和缺点一些
工具是基于PC 用户的强调易用性而另一些则是为超大型数据库提供的本部分将向
您介绍选择这些工具的关键所在
注为了SQL 在实际中的使用本书中举出了一些SQL 在实际开发环境中的应用例
子SQL 只有出现在你的代码中为你真正地解决了问题才说明它是有用的
Microsoft Access
在一些应用实例中我们将会举一些Microsoft Access 的例子Microsoft Access 是一个
非常容易使用的基于PC 机的数据库管理系统在它的下边你既可以手工输入SQL 语句也
可以使用图形用户界面工具来生成SQL 语句
Personal Oracle7
我们使用Personal Oracle7 来向大家演示SQL 对大型数据库上的命令行使用方法当
用户对一个数据库或一个操作系统有充分的了解以后需要在一个孤立的电脑上进行设计
时这种方法是非常重要的在命令行下用户可以在SQL PLUS 工具中输入不同的单的SQL
语句该工具可以把数据返回给用户或是对数据库进行适当的操作
大多数例子是针对初用SQL 进行程序设计的程序员的我们从最简单的SQL 语句开
始并进阶到事务处理阶段为程序设计做好准备Oracle 的发行版提供一整套的开发工具
它包括C++和Visual Basic 函数库(Oracle Objects for OLE) 通过它可以将应用程序与
ORACLE 个人数据库链接在一起它也可以为数据库用户或管理员提供图形工具同
SQL*Loader 一样它也经常用于从Oracle 数据库中导出或引入数据
注Personal Oracle7 是Oracle7 server 的不完整版它只允许单用户操作就如同它的名字
一样但它在SQL 的语法使用与大型更昂贵的Oracle 版本是相同的此外在Personal
Oracle7 中所使用的工具也适用于Oracle 的其他版本
我们选择Personal7 基于以下原因
l 它几乎用到了本书中将要讨论的所有工具
l 它是可以在几乎全部的平台运行的风靡世界的关系型数据库管理系统
l 可以从Oracle 公司的服务器上下载一个它的90 天限时版(http://www.oracle.com).
上图显示了SQL-PLUS 的一个画面
技巧注意在本书中所给出的所有SQL 代码都适用于其它的数据库管理系统防止在其它
的系统中语法出现大的差别在本书的例子中指出了它在其它系统中的不同之处
Microsoft Query
Microsoft Query 是Microsoft 公司的Visual C++和Visual Basic 开发工具包中所附带的
一个非常有用的查询工具它可应用在基于ODBC 标准下的数据库该查询工具在将查询
语句提交给数据库之前会将基保留在驱动器上
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 28
开放型数据库联接ODBC
ODBC 是为应用程序接口API 提供的访问下层数据库所
用的函数库它通过数据库引擎与数据库交流就像在Windows
通过打印驱动程序与打印机通信那样为了访问数据库可能还
会需要网络驱动程序与异地数据库通信ODBC 的结构如右图所

ODBC 的特色在于它不是针对任何一种数据库的举例来说
你可以用相同的代码来在Microsoft Access 表中或Informix
database 上运行查询而无需修改代码或只需做很小的改动再
提醒您一次第三方数据库供应商可能会在SQL 的标准之上对其
进行扩充比如Microsof 和Sybase 的Transact-SQL 以及Oracle
的PL/SQL
当您用一种新型的数据库工作时您应该认真阅读一下它的文档ODBC 是许多数据库
所支持的一种标准包括Visual Basic Visual C++ FoxPro Borland Delphi 和PowerBuilder
基于ODBC 所开发的应用程序有着明显的优势因为它允许你在编写代码的时候不必考虑
是为哪一个数据库所写的当然它的运行速度要弱于特定的数据库代码也就是说在使
用ODBC 的时候其灵活性更强但比起使用Oracle7 或Sybase 的函数库时要慢
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 29
SQL 在编程中的应用
SQL 的最初标准是ANSI-1986 而在ANSI-1989 中定义的SQL 在应用程序中的三种
接口类型
l 模块语句— — 在程序中使用过程该过程可以通过主调参数向主调函数返回值
l 内嵌SQL — — 可以在编写程序的过程中内嵌SQL 语句该方式在经常需要对SQL
语句进行预编译处理时所需要在Pascal FORTRAN COBOL PL/1 中均定义
了这样的子句
l 直接调用— — 由程序直接实现
在动态SQL 发展以前内嵌SQL 在编程中应用最为流行这种方法在今天也仍然在
使用由于静态的SQL — — 它的意思就是SQL 语句已经被编译在了应用程序之中不能在
运行的过程中改变这与编译程序同解释程序的区别类似也就是说这种类型的SQL 速度
很快但是灵活性很差这在今天的商业应用领域是不适宜的动态SQL 这里就不多说了
ANSI-92 标准将SQL 语言标准扩展为一种国际化的标准它定义了SQL 的三种编译
级别登录调用内嵌子句和完全编译主要的新特性如下
l 联接到数据库
l 移动游标
l 动态SQL
l 外连接
本书除了这些扩展以外还包括了第三方数据库供应商所提供的扩展动态SQL 允许你
在运行时修改SQL 语句但是它的速度要比内嵌型SQL 慢它在调用级接口上为应用程
序开发人员提供了相当大的灵活性ODBC 或Sybase 的DB-Library 就是动态SQL 的例子
调用级接口对于编程人员来说不是一个新概念当您在使用ODBC 时举例来说你
需要在SQL 语句提交给数据库时修改子句中的变量参数而使用该功能在设计阶段可以通
过使用其它的函数调用接收错误信息或结果结果是以数据包的形式返回的
摘要
在第一天介绍了SQL 的历史由于SQL 与关系型数据库是紧密结合的所以第一天也简
要地介绍了关系型数据库的历史和它的功能明天我们将讲述SQL 中最为常用的功能— —
查询
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 30
问与答
问为什么我要了解SQL
答到现在为止如果你不知道如何利用大型数据库来进行工作如果你要使用客户机/服
务器型应用程序开发平台如Visual Basic Visual C++ ODBC Delphi 和
PowerBuilder 以及一些已经移植到PC 平台上的大型数据库系统如Oracle 和
Sybase 来进行开发工作那么你只有学习SQL 的知识在今天大多数的商用程序开
发都需要你了解SQL
问在学习SQL 时我为什么要了解关系型数据库系统
答SQL 在为关系型数据库系统开发的不知道点关系型数据库系统的知识你就无法有效
地使用SQL
问在GUI 图形用户界面工具下我只需按按钮就可以写出SQL 语句为什么我还需要学
习手工写SQL
答GUI 有GUI 的方法手工有手工的方法一般说来手工写出来的SQL 比GUI 写出来
的更有效率GUI 的SQL 语句没有手工写出的易读而且如果你知道如何用手工来写
SQL 的话那么你在使用GUI 时就会有更高的效率
问既然SQL 是一种标准化语言那是不是说我可以用它在任何数据库下进行编程
答不是你只能将它用于支持SQL 的关系型数据库系统如MS-Access Oracle Sybase
和Informix 尽管不同的系统在执行时有所差别但是你只需要对你的SQL 语句进行
很小的调整
校练场
在校练场里我们提出了一些问题以帮助你巩固自己所学这些练习可以提高你在学习中
的经验请试着回答和练习附录五问答与练习中的内容
1 为什么说SQL 是一种非过程型语言
2 我如何知道一种数据库系统是不艺机是关系型数据库系统
3 我可以用SQL 来做什么
4 把数据清楚地分成一个个唯一集的过程叫什么名字

练习
确认一下你所使用的数据库系统是否是一个关系型数据库系统
gototop
 

第二天查询— — SELECT 语句的使用
目标
欢迎来到第二天在今天你将学习到以下内容
l 如何写SQL 的查询
l 将表中所有的行选择和列出
l 选择和列出表中的选定列
l 选择和列出多个表中的选定列
背景
在第一天中我们简要地介绍了关系型数据库系统所具有的强大功能在对SQL 进行了
简要的介绍中我们知道了如何同它进行交流最终我们将会与计算机用一种非常清楚
果断的话说给我看一下所有在本公司中工作十年以上左撇子蓝眼睛的外国人如
果你能够这样做与计算机交流而不是查他们的档案每一个人都可以用他自己的方法
来达到目的但是你却是用SQL 的一种重要功能— — 查询来达到目的
在第一天中我们说过查询一词用在SQL 中并不是很恰当在SQL 中查询除了向数
据库提出问题之外还可以实现下面的功能
l 建立或删除一个表
l 插入修改或删除一个行或列
l 用一个特定的命令从几个表中查找所需要的信息并返回
l 改变信息的安全性
SQL 的查询当然也能进行一般的查询工作在学会使用这个有用的工具之前我们来
学习如何写SQL 的查询语句
一般的语法规则
正如你所看到的那样SQL 有很高的灵活性尽管在任何程序中都有一定的规则限制
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 33
下而有一个SQL 中SELECT 语句使用的简单例子请注意在每个SQL 语句的关键字都
是大写的并且用空格将他们划分出来
SELECT NAME STARTTERM ENDTERM
FROM PRESIDENTS
WHERE NAME LINCOLN
在这个例子中每一个字母都是大写的但是这不是必需的上边的查询语句完全可以
写成这样
select name startterm endterm
from presidents
where name LINCOLN
注意LINCOLN 在这里仍然是大写的尽管SQL 语句对大小写并不敏感但在数据
库中的数据却是大小写敏感的举例来说许多公司在储存数据时用大写字母在这种情
况下所有的字段名也将是大写字母那么在检索条件为name='Lincoln'的数据时将不会得
到任何结果这种情况在每个实例应用中都会遇到
注意在SQL 语句中大小写是不敏感的
现在我们来看另一个例子在这个例子中的空格有问题吗不是这个语句完全可以
正常执行
Select name startterm endterm from presidents where name='LINCOLN'
但是如果你注意在你的语句中使用空格和大写字母会增强语句的可读性当它变成
你的工程编程的一部分时会更便于维护
另一个重要的特性是分号当在SQL 语句中出现分号就意味着本条语句已经结束
为什么在格式中大小写是不重要的原因何在答案是— — 关键字关键字是SQL 语
法中的保留字在SQL 语句中关键字是可选择的但其内容有强制性在本例中的关键
字有
SELECT
FORM
WHERE
看一下目录你会找到需要在其它几天中学习的关键字
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 34
数据报的形成— — SELECT 和FROM
随着对SQL 的了解你会发现你键入的SELCT 和FROM 在远远多于其它的关键字
它不像CREATE 那样迷人或像DROP 那样残忍但是如果你在同计算机会话并需要计算机
返回结果时它们却是必不可少的这与最初选择何种数据库没有关系
我们先从SELECT 开始讨论因为SELECT 是在SQL 中使用最为频繁的语句
语法
SELECT <列名>
没有其它的语句可以比SELECT 语句更简单了但是SELECT 语句不从独立工作如
果你只是键入了SELECT 语句那么你将会收到如下信息
输入
SQL> SELECT;
输出
SELECT
*
ERROR at line 1
ORA-00936 missing expression
当在访问ORACLE 时会有*出现以表示有事件产生错误信息的意思是告诉你有一个
东西丢了这个丢失的东西就是FROM 子句
语法
FROM <表名>
当两条语句结合使用时就有了后台访问数据库的能力
注你可能会对子句关键字或SQL 语句感到费解SQL 的关键字是SQL 中的特定元
素如SELECT 和FROM 子句则是SQL语句的一部分如, SELECT column1, column2, ...
就是一个子句而SQL 语句则是几个子句的结合例如你可以将SELECT 子句和FROM
子句组合成为一个SQL 语句
注每一个种SQL 都有其特定的出错信息例如Microsoft Query 会显示说它不能运行查
询并引导你发现错误所在Borland's Interbase 将会弹出一个错误对话框Personal
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 35
Oracle7 的引擎将会出现如前所述的信息并给出一个错误号码所以当你手工输入SQL
语句时会看到详细的错误信息以及对错误的简要诠释
例子
在进一步学习之前我们先来看一个将要在下面的例子中用到的数据库这个数据库
体现了SELECT 和FROM 的基本功能在实际应用时我们将会用到在第8 天熟练地操作
数据中讲到的技巧来构建这个数据库但是我们现在的目的是学习如何使用SELECT 和
FROM 所以我们假设数据库已经建好了本例中使用CHECKS 表这个表的内容如下
CHECK# PAYEE AMOUNT REMARKS
1 MaBell 150 Havesonsnexttime
2 ReadingR.R. 245.34 TraintoChicago
3 MaBell 200.32 CellularPhone
4 LocalUtilities 98 Gas
5 JoesStale$Dent 150 Groceries
6 Cash 25 WildNightOut
7 JoansGas 25.1 Gas
gototop
 

你的第一个查询
输入
SQL>select * from checks
输出
CHECK# PAYEE AMOUNT REMARKS
1 Ma Bell 150 Have sons next time
2 Reading R.R 245.34 Train to Chicago
3 Ma Bell 200.32 Cellular Phone
4 Local Utilities 98 Gas
5 Joes Stale $ Dent 150 Groceries
6 Cash 25 Wild Night Out
7 Joans Gas 25.1 Gas
7 rows selected.
分析
请看例子的输出结果注意第1 列和第3 列是右对齐的而第2 列和第4 列是左对齐的
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 36
这是因为对于数字类型采用右对齐而对于字符类型则是采用左对齐的数据的类型将在第
9 天的表的建立与维护中讨论
在SELECT 中的*表示要返回FROM 中所指定的表中的所有列并按照数据库中的固
有顺序来排序
完成一个SQL 语句
在SQL 运行时分号即意味着通知解释程序当前语句已经结束例如SQL*PLUS
在没有遇到分号时将不会执行语句但是在其它的SQL 解释器中可能不会用到分号例如
Microsoft Query 和Borland's ISQL 不需要查询终止符因为你是在编辑框中输入查询语句
并且当你在按下按钮以后才开始执行查询
对列进行排序
在前边的例子中使用了*来选择了选定表格中的所有列并且是按照其在数据库中的固
定顺序来排序的如果需要对特定的列排序你应该按下边所写的那样输入
输入
SQL> SELECT payee remarks amount check# from checks;
注意在SELECT 子句中给出了每个列的名字排序是根据列的先后顺序来进行的注
意将最后列的列名与其后的子句这里是FROM 用空格分开输出的结果如下
输出
PAYEE REMARKS AMOUNT CHECK#
Ma Bell Have sons next time 150 1
Reading R.R. Train to Chicago 245.34 2
Ma Bell Cellular Phone 200.32 3
Local Utilities Gas 98 4
Joes Stale $ Dent Groceries 150 5
Cash Wild Night Out 25 6
Joans Gas Gas 25.1 7
7 rows selected.
这句话也可以写成下边的形式
输入
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 37
SELECT payee, remarks, amount, check#
FROM checks;
注意这里的FROM 子句已经写到第二行了这是一种个人习惯其输出的结果如下
输出
PAYEE REMARKS AMOUNT CHECK#
Ma Bell Have sons next time 150 1
Reading R.R. Train to Chicago 245.34 2
Ma Bell Cellular Phone 200.32 3
Local Utilities Gas 98 4
Joes Stale $ Dent Groceries 150 5
Cash Wild Night Out 25 6
Joans Gas Gas 25.1 7
7 rows selected.
分析
语句的格式变更不会对输出的结果造成影响现在你已经知道了如何对输出的结果进
行排序试着将表格的列按照你的要求进行排序
选择特定的列
如果你不想看到数据库中的每一列当然你使用SELECT *将所有的列显示出是可
行的但是如果你只想看一下CHECKS 中的号码与数量列那么你可以输入如下语句
输入
SQL> SELECT CHECK#, amount from checks;
输出
CHECK# AMOUNT
1 150
2 245.34
3 200.32
4 98
5 150
6 25
7 25.1
现在你可以按要求显求所需要的列注意大小写的使用它不会对查询的结果造成影
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 38

如何从不同的表中查找到所需要的信息呢
从不同的表中选择
假设你有一个名为DEPOSITS 表其内容如下
输出
DEPOSIT# WHOPAID AMOUNT REMARKS
1 Rich Uncle 200 Take off Xmas list
2 Employer 1000 15 June Payday
3 Credit Union 500 Loan
分析
你需要对数据源作一下简单的改动
查找不重复的数据
如果你看过原来的CHECKS 表你会发现其中有一些数据是重复的例如AMOUNT

输入
SQL> select amount from checks
输出
AMOUNT
150
245.34
200.32
98
150
25
25.1
请注意150 在这里是重复的如果你只想查看不重复的数据可以这样做
输入
SQL> select DISTINCT amount from checks;
输出
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 39
AMOUNT
25
25.1
98
50
200.32
245.34
6 rows selected
分析
注意只有六行数据被选择这是因为你使用了DISTINCT 所有只有不重复的数据才
会被显示ALL 是在SELECT 中默认的关键字你几乎从来也不会用到ALL 因为SELECT
与SELECT ALL 是等价的
试一下这个例子作为你对SQL 的第一次也是唯一的一次实际体验
输入
SQL> SELECT ALL AMOUNT
FROM CHECKS;
输出
AMOUNT
150
245.34
200.32
98
150
25
25.1
7rowsselected.
它的结果与SELECT <Column>是相同的谁还会再去用这个多余关键字呢
总结
关键字SELECT 可以检索数据库并从中返回数据你可以用一个很长的语句并使用
SELECT *来检索数据库中的所有表而且你可以对指定表格的结果进行重新排序而关键
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 40
字DISTINCT 则会强制性地要求返回的结果中不能有重复数据明天我们将学习如何使您
的查询更具有选择性
问与答
问这些数据是从哪里来的我们是如何得到它的
答数据是按照第8 天所讲述的方法创建的与数据库的联接是依靠你所使用的SQL 它
以传统的命令行方式与数据库进行会话该数据库原来属于服务器或客户机范畴但
最近它已经被移植到了PC 机上
问可是我用不到这些数据库那我还可以用SQL 干什么
答你也可以在编程语言中使用SQL 一般的编程语言都支持内嵌的SQL 例如COBOL
你可以在它的环境中写SQL 并编译而Microsoft 公司则提供了应用程序接口函数以
允许编程人员在Visual Basic C 或C++中使用SQL Sybase and Oracle 提供的库也
允许你在编程时使用SQL Borland 公司则将SQL 置于Delphi 中本书中也将讨论SQL
在编程中的应用
校练场
在校练场里我们提出了一些问题以帮助你巩固自己所学这些练习可以提高你在学习
中的经验请试着回答和练习附录五问答与练习中的内容在开始明天的工作之前要
确保你已经知道了这些问题的答案
1 下列语句所返回的结果是否相同
SELECT * FROM CHECKS;
select * from checks
2 为什么下列查询不会工作
a. Select * b. Select * from checks
c. Select amount name payee FROM checks;
3
A select *
From checks
B select * from checks
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 41
C select * from checks
/
练习
1 使用今天早些时候的CHECKS 表的数据来写一个查询返回表中的number 和remark
列中的数据
2 将练习1 中的查询再写一遍以使得remark 列出现在第一位
3 使用CHECKS 表写一个查询来返回其中的不重复数据
gototop
 

第三天表达式条件语句与运算
目标
在第二天我们学习了使用SELECT 语句和FROM 语句来对数据进行有趣味性也是非常有
用的运算在今天我们将对昨天学习的进行进一步的扩充我们将把新的方法应用到查
询表和行中引进新的子句和被称为运算的批量处理方法在第三天的阳光下你将学

知道什么叫作表达式以及如何来使用它们
知道什么叫作条件语句以及如何来使用它们
熟悉基本的子句WHERE 的使用
可以用算术比较字符和逻辑表达式来建立一个运算
学会将多种不同的运算结合在一起使用
注在今天的学习中我们来使用PERSONAL ORACLE7 来进行应用举例其它的SQL 环
境在命令运算以及结果显示上与它稍有不同但在遵循ANSI 标准的基础上它们的结果应
该是相同的
表达式
表达式的定义非常简单表达式可以返回一个值表达式的类型非常广泛它以包括各种
类型的数据如数字字符以逻辑型等其实在下列子句如SELECT 和FROM 中所占
成分中表达式最大在下边的例子中amount 就是一个表达式它可以返回amount 列中的
数据
SELECT amount FROM checks
而在下列语句中NAME ADDRESS PHONE ADDRESSBOOK是表达式
SELECT NAME, ADDRESS, PHONE
FROM ADDRESSBOOK
现在请检查一下下边的表达式
WHERE NAME = 'BROWN'
这里NAME = 'BROWN'是一个条件语句这是一个逻辑形表达式的实例NAME =
'BROWN'将根据=号来返回值TRUE 或FALSE
条件
如果你想在数据库中查找一个或一组特定的信息你需要使用一个或更多的条件条件可
以包含在WHERE 子句中在上一个例子中条件就是
NAME = 'BROWN'
如果你想知道在你们单位中上一个月有谁的工作时间超过了100 个小时你可能会写出下
边的条件语句
NUMBEROFHOURS > 100
条件语句可以让你建立一个选择查询在大多数情况下条件中包括变量常量和比较运
算在第一个例子中的变量是NAME 常量是'BROWN' 而比较运算符则为= 在第二个
例子中变量为NUMBEROFHOURS,常量为100 而比较运算符则是> 当您准备写一个条
件查询时你需要知道两个元素WHERE 子句和运算
WHERE 子句
Where 子句的语法如下
WHERE <SEARCH CONDITION>
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 43
Select From 和Where 在SQL 中最常使用的三个子句Where 只是当你的查询具有更大的
选择性没有Where 子句你可以用查询做得最多的有用工作是显示选定表中的所有记录
例如
输入
SQL> SELECT * FROM BIKES
这将会将BIKES 表中的所有数据按行列出
输出
NAME FRAMESIZE COMPOSITION MILESRIDDEN TYPE
TREK 2300 22.5 CARBONFIBER 3500 RACING
BURLEY 22 STEEL 2000 TANDEM
GIANT 19 STEEL 1500 COMMUTER
FUJI 20 STEEL 500 TOURING
SPECIALIZED 16 STEEL 100 MOUNTAIN
CANNONDALE 22.5 ALUMINUM 3000 RACING
假若你想要一台特定型号的自行车你应该键入
SQL> SELECT FROM BIKES WHERE NAME = BURLEY
你将只会收到一个记录
输出
NAME FRAMESIZE COMPOSITION MILESRIDDEN TYPE
BURLEY 22 STEEL 2000 TANDEM
分析
这个简单的例子显示出了你可以在数据库返回的数据中加以条件限制
运算
运算是你需要对从数据库中返回的数据进行数学处理时所用到的元素运算可以归为六组
数值型比较型字符型逻辑型和备注型以及混合型
数值型运算
数值型运算有加减乘除和取模前四个不用多说取模将返回一个除法结果中商的
余数部分这里有两个例子
5%2=1
6%2=0
对于有小数的数据不能应用取模运算如实数
如果你在进行数据运算时应用了几个运算符而没有在其中使用括号那么运算进行的次序
将是先乘后除再模后加减举例来说表达式2*6+9/3 其结果将是12+3=15 但是表
达式2* 6+9 /3 结果则为2*15/3=10 注意在这里你使用了括号有时表达式不会按你所
想像的那样得出期望的结果
加法(+)
你可以在许多场合下使用加号下面的语句将显示一个价格表
输入SQL> SELECT * FROM PRICE
输入如下右
现在请输入
SQL>SELECT ITEM WHOLESALE WHOLESALE 0.15 FROM PRICE OUTPUT
ITEM WHOLESALE
TOMATOES .34
POTATOES .51
BANANAS .67
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 44
ITEM WHOLESALE
TURNIPS .45
CHEESE .89
APPLES .23
这里对于下列产品的每一个价格数据加了15 分
ITEM WHOLESALE WHOLESALE+0.15
TOMATOES .34 .49
POTATOES .51 .66
BANANAS .67 .82
TURNIPS .45 .60
CHEESE .89 1.04
APPLES .23 .38
分析
请不要忽视最后一列WHOLESALE+0.15 它在原始的数据库表中没有切记你在SELECT
中使用了*号这将会显示出所有的列SQL 允许你创建一个虚拟列或对已有的列进组合
和修改后产生的派生列
请再输入一次刚才的语句
SQL> SELECT * FROM PRICE
右面是从表中返回的结果
ITEM WHOLESALE
TOMATOES .34
POTATOES .51
BANANAS .67
TURNIPS .45
CHEESE .89
APPLES .23
分析
输出的结果有时原始数据并没有被改变而标题为WHOLESALE+0.15 的列也不是表中的
固有列事实上由于这个列标题太不容易为人所注意所以你应该在它的上边再花一些
工夫
请输入
SQL> SELECT ITEM WHOLESALE WHOLESALE 0.15 RETAIL
FROM PRICE
其结果如右
ITEM WHOLESALE RETAIL
TOMATOES .34 .49
POTATOES .51 .66
BANANAS .67 .82
TURNIPS .45 .60
CHEESE .89 1.04
APPLES .23 .38
分析
gototop
 

真棒你不但可以创建一个新列而且还可以对它安自己的需要进行重命名你可以按语
法列名别名来对任何一个列进行重命名注意在列名与别名之间有空格
例如输入
SQL> SELECT ITEM PRODUCE WHOLESALE WHOLESALE 0.25 RETAIL
FROM PRICE
重命名的列如下
PRODUCE WHOLESALE RETAIL
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 45
TOMATOES .34 .49
POTATOES .51 .66
BANANAS .67 .82
TURNIPS .45 .60
CHEESE .89 1.04
APPLES .23 .38
注一些SQL 解释器使用的语法为列名= 别名所以前一个例子要写成如下格式
SQL> SELECT ITEM PRODUCE
WHOLESALE
WHOLESALE 0.25 RETAIL
FROM PRICE
请检查你的SQL 解释器以确认它采用哪一种语法
你大概想知道当不在命令行状态时应如何使用别名吧很清楚你知道报表生成器是如何
工作的吗总有一天当有人让你写一个报表的生成器时你就会记住它而且不用却重复
Dr Codd 和IBM 已经做过的工作
到现在为止你已经看到了两种加号的用法第一种用法是在SELECT 子句中使用+号以
执行对数据的运算并将结果显示出来第二种用法是在WHERE 子句中使用加号在WHERE
中使用操作符可以在当你对数据有特定条件时具有更大的灵活性
在一些解释器中加号还同时肩负着进行字符运算的责任在稍后的几天中你将会看到这
一点
减法—
减号也有两种用途第一种用途是作为负号使用你可以使用HILOW 表来验证这项功能
SQL> SELECT * FROM HILOW
输出
STATE HIGHTEMP LOWTEMP
CA -50 120
FL 20 110
LA 15 99
ND -70 101
NE -60 100
例如这里对数据进行这样的运算
SQL> SELECT STATE HIGHTEMP LOWS LOWTEMP HIGHS FROM HILOW
STATE LOWS HIGHS
CA 50 -120
FL -20 -110
LA -15 -99
ND 70 -101
NE 60 -100
第二种用法很明显是作为减号从某一列中减去另一列例如
SQL> SELECT STATE
HIGHTEMP LOWS
LOWTEMP HIGHS
(LOWTEMP - HIGHTEMP) DIFFERENCE
FROM HILOW
STATE LOWS HIGHS DIFFERENCE
CA -50 120 170
FL 20 110 90
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 46
LA 15 99 84
ND -70 101 171
NE -60 100 160
注意这里使用了别名来对输入的错误进行更正这只不过是一种暂时的补救方法虽然这
不是永久的解决办法你是以后第21 天常见的SQL 错误及其解决方案会看到如何
对数据以及输入进行更正在那里你将学会如何对错误的数据进行更正
该查询不只是修正至少看起来是这样错误的数据而且还创建了一个新列以获得每个
记录的最高与最低的差价
如何你在一个字符型字段中意外地使用了减号你将会看到如下信息
SQL> SELECT STATE FROM HILOW
ERROR ORA-01722 invalid number
No rows selected
在不同的解释器中错误的号码可能会不同但是结果是相同的
除法
除法只有一种显而易见的应用在PRICE 表中它的应用如下
输入
SQL> SELECT * FROM PRICE
输出:
ITEM WHOLESALE
TOMATOES .34
POTATOES .51
BANANAS .67
TURNIPS .45
CHEESE .89
APPLES .23
rows selected.
在下边的例句中你可以成功地将销售价折半
输入/输出
SQL> SELECT ITEM WHOLESALE (WHOLESALE/2) SALEPRICE 2 FROM PRICE
ITEM WHOLESALE SALEPRICE
TOMATOES .34 .170
POTATOES .51 .255
BANANAS .67 .335
TURNIPS .45 .225
CHEESE .89 .445
APPLES .23 .115
6 rows selected.
在这个SELECT 语句中除法的作用是显而易见的只不过将商品半价销售有点太难以理解

乘法*
乘法的运算也非常直观再以Price 表为例
输入
SQL> SELECT * FROM PRICE
输出
ITEM WHOLESALE
TOMATOES .34
POTATOES .51
BANANAS .67
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 47
TURNIPS .45
CHEESE .89
APPLES .23
6 rows selected.
将表中的价格下调10%可以用如下方法来实现
输入/输出:
SQL>SELECT ITEM WHOLESALE WHOLESALE * 0.9 NEWPRICE
FROM PRICE
ITEM WHOLESALE NEWPRICE
TOMATOES .34 .306
POTATOES .51 .459
BANANAS .67 .603
TURNIPS .45 .405
CHEESE .89 .801
APPLES .23 .207
6 rows selected.
通过这些操作您可以在SELECT 语句中进行复杂的运算
取模%
取模运算将返回一个除法的余数部分以REMAINS 表举例如下
输入
SQL> SELECT * FROM REMAINS
输出
NUMERATOR DENOMINATOR
10 5
8 3
23 9
40 17
1024 16
85 34
6 rows selected.
gototop
 

你也可以用NUMERATOR % DENOMINATOR 的结果来建立一个新列
输入/输出
SQL> SELECT NUMERATOR DENOMINATOR NUMERATOR%DENOMINATOR
REMAINDER FROM REMAINS
NUMERATOR DENOMINATOR REMAINDER
10 5 0
8 3 2
23 9 5
40 17 6
1024 16 0
85 34 17
6 rows selected.
在一些SQL 解释器中取模运算符为MOD 见第4 天函数— — 返回数据的再加工下边
的语句所得到的结果与上边的语句相同
SQL> SELECT NUMERATOR DENOMINATOR MOD NUMERATOR DENOMINATOR
REMAINDER FROM REMAINS
优先级别
在这一部分的例子中主要讲述在SELECT 语句中的优先级别数据库PRECEDENCE 的内
容如下
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 48
SQL> SELECT * FROM PRECEDENCE
N1 N2 N3 N4
1 2 3 4
13 24 35 46
9 3 23 5
63 2 45 3
7 2 1 4
用PRECEDENCE 来做如下例子
输入/输出
SQL> SELECT
2 N1+N2*N3/N4
3 (N1+N2)*N3/N4
4 N1+(N2*N3)/N4
5 FROM PRECEDENCE
N1+N2*N3/N4 (N1+N2)*N3/N4 N1+(N2*N3)/N4
2.5 2.25 2.5
31.26 28.15 31.26
22.8 55.2 22.8
93 975 93
7.5 2.25 7.5
看到了吗第一例与最后一例的结果是相同的如果你把第四列改写成为N1+N2*
(N3/N4) 那么其结果与上边的例子是相同的
比较运算
顾名思义比较运算就是将两个表达式进行比较并返回三个数值中的一个
True,False,Unknow,请等一下Unknow True 和False 的意义无需说明但是什么是Unknow

为了便于理解什么是Unknow 你需要理解一下什么是NULL 在数据库领域内NULL
的意义就是在一个字段之中没有数据这与在该字段中数据为零或为空的不是同一个概念
为零或为空是一种特殊的数值而NULL 则表示在这个字段之中什么也没有如果你想进
行Field=9 的比较而Field 字段是空的那么比较的结果就会返回Unknow 由于Unknow
是一种不正常的状态所以大多数SQL 都会置其为无效并提供一种叫IS NULL 的操作来
测试Null 的存在
输入
SQL> SELECT * FROM PRICE
输出
ITEM WHOLESALE
TOMATOES .34
POTATOES .51
BANANAS .67
TURNIPS .45
CHEESE .89
APPLES .23
ORANGES
请注意WHOLESALE 字段在ORANGES 处没有输出这说明在这里的数值是空的由于
这里的WHOLESALE 字段的属性为数字所以空值在这里是显而易见的但是如果空值
是出现在ITEM 列中那么要将空值与空白值区分开来就是非常重要的了
请试着找一下空值
输入/输出:
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 49
SQL> SELECT * FROM PRICE WHERE WHOLESALE IS NULL
ITEM WHOLESALE
ORANGES
如你所见到的WHOLESALE 字段中的ORANGES 是唯一的一个空值因为它是不可见
的可是当你使用= 这个比较运算符时会有什么结果呢
输入/输出:
SQL> SELECT * FROM PRICE WHERE WHOLESALE = NULL
No rows selected
分析
你没有得到任何记录因为比较运算在这里返回的结果为FALSE 所以使用WHERE
SWHLESALE IS NULL 在这里比使用=更恰当它将会返回所有存在空值的记录
这个例子也是对使用= 进行的比较操作进行的完全展示这之中的WHERE 子句就不
用多说了下面简要说一下等号
在今天的早些时候你已经看到了在一些SQL 解释器中等号可以在SELECT 子句中用以给
搜索字段赋以别名而在WHERE 子句中它则用于比较操作并且它是从多个记录中捡选
所需要数值的一种有效手段试一下
输入
SQL> SELECT * FROM FRIENDS
输出
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP(邮政编码)
BUNDY AL 100 555-1111 IL 22333
MEZA AL 200 555-2222 UK
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
现在让我们来找一下JD.MAST 的记录信息(在我们的这个表中这很容易但是你的朋友可
能不只这些也许像这样的记录你有成千上万)
输入/输出
SQL> SELECT * FROM FRIENDS WHERE FIRSTNAME = 'JD'
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MAST JD 381 555-6767 LA 23456
结果如我们所愿再试一下
输入/输出
SQL> SELECT * FROM FRIENDS WHERE FIRSTNAME = 'AL'
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
BUNDY AL 100 555-1111 IL 22333
MEZA AL 200 555-2222 UK
注你应该看到在这里= 号返回了多个记录注意第二个记录的邮政编码ZIP 是空
的邮政编码是一个字符型字段你将在第8 天学习如何创建和组装一个表这个特殊的
空字段表明在字符型字段中空字段与空白字段是不同的
此外还有一个关于敏感性的问题试一下
输入/输出
SQL> SELECT * FROM FRIENDS WHERE FIRSTNAME = BUD
FIRSTNAME
BUD
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 50
1 row selected
再试一下
输入/输出
SQL> select * from friends where firstname = Bud
No rows selected
分析
尽管SQL 对大小写是不敏感的但是数据库中的数据对大小写却是敏感的大多数公
司在存储数据时采用大写以保证数据的一致性所以你应该永远采用大写或小写来存储数
据大小写的混合使用会对你精确地查找数据造成障碍
gototop
 

大于与大于等于
大于操作的使用方法如下
输入:
SQL> SELECT * FROM FRIENDS WHERE AREACODE > 300
输出
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
分析
这个操作将显示所有比区号比300 大的记录但是不包括300 如果要包括300 应写
成如下方式
输入/输出
SQL> SELECT * FROM FRIENDS WHERE AREACODE>=300
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
当然你使用AREACODE>299 时会得到相同的结果
注在这个语句中300 没有使用引号对于数字型字段是不需要加引号的
小于与小于等于
如你所料它们的使用方法与大于和大于等于操作相同但结果相反
输入
SQL> SELECT * FROM FRIENDS WHERE STATE< LA
输出
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
BUNDY AL 100 555-1111 IL 22333
MERRICK BUD 300 555-6666 CO 80212
BULHER FERRIS 345 555-3223 IL 23332
注为什么STATE 会变成ST 呢这是因为这一列只有两个字符宽所以结果只会返回两
个字符如果列为COWS 那么它将会显示成CO 而AREACODE 和PHONE 所在列的
列宽大于它们自身的名字所以它们不会被截去
分析
请等一下你现在知道<在字符字段中的用法了吗当然知道了你可以在各种数据类型
中进行你想要的比较操作结果会因数据类型的不同而不同例如你在下例中使用小写
字符
输入/输出
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 51
SQL>SELECT * FROM FRIENDS WHERE STATE < la
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
BUNDY AL 100 555-1111 IL 22333
MEZA AL 200 555-2222 UK
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
分析
因为大写的字母代码比小写的小所以大写的字符总是排在小写字符的前面这里再说一
次为了保证安全请在执行前检查大小写情况
技巧想知道你所进行操作的结果那你先要检查一下你的电脑所采用的字符编码集PC
机解释器使用的是ASCLL 编码而其它平台则使用EBCDIC 编码
要想在结果中显示Louisiana 键入
输入/输出
SQL> SELECT * FROM FRIENDS WHERE STATE<= LA
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
BUNDY AL 100 555-1111 IL 22333
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
不等号<>或!=
如果你想要查找一些除了确定信息以外的其它信息那你可以使用不等号由于SQL 的解
释器不同它可能写做<> 或!= 如果你想找除了AL 以外的人你可以写出
输入:
SQL> SELECT * FROM FRIENDS WHERE FIRSTNAME <> AL
输出
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
想找一下不在California 住的人可以写成
输入/输出:
SQL> SELECT * FROM FRIENDS WHERE STATE != CA
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
BUNDY AL 100 555-1111 IL 22333
MEZA AL 200 555-2222 UK
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
注意=和<>符号都表示不等于
字符操作
无论数据的输出是否为有条件输出你都可以对其中的字符串进行操作本部分将会讲述
两个操作符LIKE 和|| 以及字符串连接的概念
LIKE
如果你想从数据库中选出一部分数据并把它们添到一个模板中并且不需要非常精确的匹
配你可以用= 来对每一种可能的情况进行操作但是这一过程烦琐而又耗时这时
你可以使用LIKE 如下例
输入
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 52
SQL>SELECT * FROM PARTS
输出
NAME LOCATION PARTNUMBER
APPENDIX MID-STOMACH 1
ADAMSAPPLE THROAT 2
HEART CHEST 3
SPINE BACK 4
ANVIL EAR 5
KIDNEY MID-BACK 6
你怎样找出其中有BACK 的记录呢粗看一下这里有两个记录可不幸的是它们有一点差

请试一下
输入/输出:
SQL>SELECT * FROM PARTS WHERE LOCATION LIKE %BACK%
NAME LOCATION PARTNUMBER
SPINE BACK 4
KIDNEY MID-BACK 6
你可能注意到了在这条语句的LIKE 后边使用了% 在LIKE 表达式中%是一种通配符
它表示可能在BACK中出现的其它信息如果你输入如下
输入
SQL>SELECT * FROM PARTS WHERE LOCATION LIKE BACK%
你将会检索到所有以BACK开头的LOCATION 记录
输出
NAME LOCATION PARTNUMBER
SPINE BACK 4
如果你输入
输入
SQL> SELECT * FROM PARTS WHERE NAME LIKE A%
你将会得到所有NAME 中以开头的记录
输出
NAME LOCATION PARTNUMBER
APPENDIX MID-STOMACH 1
ADAMS APPLE THROAT 2
ANVIL EAR 5
那么LIKE 语句是否对大小写敏感呢请看下边的例子
输入/输出:
SQL> SELECT * FROM PARTS WHERE NAME LIKE 'a%'
no rows selected
分析
回答是敏感的当涉及到数据是时候总是大小写敏感的
如果你想查找在某一确定的位置上有字符的数据时你应该如何去做呢你可以使用另一个
通配符— — 下划线
下划线_
输入
SQL> SELECT * FROM FRIENDS
输出
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 53
BUNDY AL 100 555-1111 IL 22333
MEZA AL 200 555-2222 UK
MERRICK UD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
BULHER FERRIS 345 555-3223 IL 23332
PERKINS ALTON 911 555-3116 CA 95633
BOSS SIR 204 555-2345 CT 95633
如果你想查找所有以开头的州可以使用如下语句
输入/输出
SQL> SELECT * FROM FRIENDS WHERE STATE LIKE C_
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MERRICK BUD 300 555-6666 CO 80212
PERKINS ALTON 911 555-3116 CA 95633
BOSS SIR 204 555-2345 CT 95633
gototop
 

也可以在一个语句中使用多个下划线如
输入/输出
SQL> SELECT * FROM FRIENDS WHERE PHONE LIKE 555-6_6_
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
这个语句也可以写成如下形式
输入/输出
SQL> SELECT * FROM FRIENDS WHERE PHONE LIKE 555-6%
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
MERRICK BUD 300 555-6666 CO 80212
MAST JD 381 555-6767 LA 23456
看它们的结果是一样的这两个通配符也可以联合起来使用下边的例子将找出所有的
第个字母为的记录
输入输出
SQL> SELECT * FROM FRIENDS WHERE FIRSTNAME LIKE _L%
LASTNAME FIRSTNAME AREACODE PHONE ST ZIP
BUNDY AL 100 555-1111 IL 22333
MEZA AL 200 555-2222 UK
PERKINS ALTON 911 555-3116 CA 95633
连接
可以将两个字符串连接起来例如
输入
SQL> SELECT FIRSTNAME || LASTNAME ENTIRENAME FROM FRIENDS
输出
ENTIRE NAME
AL BUNDY
AL MEZA
BUD MERRICK
JD MAST
FERRIS BULHER
ALTON PERKINS
SIR BOSS
7 rows selected.
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 54
分析
请注意这里使用的是而不是号如果你试图使用号来连接两个字符串的话对于我
们使用的SQL 解释程序(Personal Oracle7)将会产生如下错误信息
输入/输出
SQL> SELECT FIRSTNAME LASTNAME ENTIRENAME FROM FRIENDS
ERROR
ORA-01722 invalid number
它试图将两个数字做加法运算但是它没有在表达式中找到任何数字
注有一些解释器也采用加号来连接字符串请检查一下你的解释器
对于连接字符串这里有更多的实例
输入/输出
SQL> SELECT LASTNAME || || FIRSTNAME NAME FROM FRIENDS
NAME
BUNDY AL
MEZA AL
MERRICK BUD
MAST JD
BULHER FERRIS
PERKINS ALTON
BOSS SIR
7 rows selected.
分析
这条语句在姓与名之间插入了一个逗号
注请注意在姓与名之间的多余的空格这些空格是数据的一部分对于确定的数据类型
空格将右填充至达到字段的设定宽度请检查你的解释器有关数据类型内容将在第9 天
的表的创建与维护中讨论
至现在为止你已经学完了所有的比较操作符对于一些问题这种方法非常好可是如果你
是想找出所有的名字中的第一个字母为P 并且他的应有的休假时间已经超过了3 天的人

逻辑运算
逻辑运算用于SQL 的WHERE 子句中将两个或更多条件组合在一起
休假的时间总是人们在工作时讨论的热门话题现在我们来为财务部门设计一个名为渡假
VACATION 的表内容如下
输入
SQL> SELECT * FROM VACATION
输出
LASTNAME EMPLOYEENUM YEARS LEAVETAKEN
ABLE 101 2 4
BAKER 104 5 23
BLEDSOE 107 8 45
BOLIVAR 233 4 80
BOLD 210 15 100
COSTALES 211 10 78
6 rows selected.
假设你的公司的雇员每年可以有12 天的休假时间现在使用你所知道的逻辑运算来实现以
下要求名字是以B 开头并且他的休假时间已经超过了50 天的员工
输入/输出
SQL 21 日自学通(V1.0) 翻译人笨猪
EMAIL wyhsillypig@163.com 55
SQL> SELECT LASTNAME YEARS * 12 LEAVETAKEN REMAINING
FROM VACATION WHERE LASTNAME LIKE B% AND
YEARS *12 LEAVETAKEN 50
LASTNAME REMAINING
BLEDSOE 51
BOLD 80
分析
这个查询语句是你讫今为止学到的最为复杂的语句SELECT 子句中使用了算术运算符来
确定每一个员工还有多少天剩余的假期标准的算式为YEARS * 12 – LEAVETAKEN 而
更为清楚的表达方法为YEARS * 12) LEAVETAKEN
LIKE 中使用了通配符%来发现所有的以B 开头的员工而比较运算的则用来发现所有休
假时间超过50 天的员工
这里我们使用了逻辑运算符号AND 来使查找到的记录同时满足两个条件带下划线的
AND
AND 只有当两个表达式的值都为真的时候才会返回真如果任意一个表达式的值不是真
那么结果就会是假的例如找一下在你的公司中工作不超过5 年但是剩余的休假时间超
过20 天的员工
输入
SQL> SELECT LASTNAME FROM VACATION WHERE YEARS<=5 AND
LEAVETAKEN>20
输出
LASTNAME
BAKER
BOLIVAR
如果你想知道在你的公司中工作时间年以上人员工和休假时间不足已有假期的的
员工呢你可以写成下边这样
输入/输出
SQL> SELECT LASTNAME WORKAHOLICS
2 FROM VACATION
3 WHERE YEARS >= 5
4 AND
5 ((YEARS *12)-LEAVETAKEN)/(YEARS * 12) < 0.50
WORKAHOLICS
BAKER
BLEDSOE
gototop
 
1234   1  /  4  页   跳转
页面顶部
Powered by Discuz!NT