SQL自学通之函数 :对数据的进一步处理
目录
COS、 COSH 、SIN 、SINH、 TAN、 TANH
一、目标
在今天我们将学习函数 在 SQL 中的函数可以执行一些储如对某一些进行汇总或或将 一个字符串中的字符转换为大写的操作 在今天结束之际 您将学会以下内容"
l 汇总函数
l 日期与时间函数
l 数学函数
l 字符函数
l 转换函数
l 其它函数
这些函数将大大加强你对这一周的早些时间所学习的 SQL 的基本功能所获得的数据的操作能力 开始的五个汇总函数 COUNT SUM AVG MAX MIN 是由 ANSI 标准 所制定的 大多数的SQL解释器都对汇总函数进行了扩充 其中有一些今天会提到 在有 些解释器这汇总函数的名称与这里所提到的不一样
二、汇总函数
这是一组函数 它们返回的数值是基于一列的 因为你不会对单个的记录求它的平均 数 这一部分的例子将使用TEAMSTATS表
输入:
SQL>SELECT FROM TEAMSTATS
输出:
COUNT
该函数将返回满足WHERE条件子句中记录的个数 例如你想知道都有哪一个球员的 击球数小于350 可以这样做
输入/输出:
SQL> SELECT COUNT( ) FROM TEAMSTATS WHERE?HITS/AB <35
为了使这段代码更易读 可以使用别名
输入/输出:
SQL>SELECT COUNT( ) NUM_BELOW_350 FROM TEAMSTATS
WHERE HITS/AB .35
如果我们用列名来替换掉括号中的星号时会结果与原来有什么不同呢 试一下
SQL> SELECT COUNT(NAME) NUM_BELOW_350 FROM TEAMSTATS
WHERE HITS/AB < 35
?
结果是一样的 因为你所选择的 NAME 列与 WHERE 子句并不相关 如果你在使用 count 时无WHERE子句 那么它将会返回表中的所有记录的个数
输入/输出:
SQL> SELECT COUNT( ) FROM TEAMSTATS
?
SUM
SUM 就如同它的本意一样 它返回某一列的所有数值的和 如果想知道队员总打点的 总和是多少 试一下
输入:
SQL>SELECT SUM(SINGLES) TOTAL_SINGLES FROM TEAMSTATS
输出:
如果想得到多个列的和 可按如下所做
输入/输出:
SQL> SELECT SUM(SINGLES) TOTAL_SINGLE,S SUM(DOUBLES)
TOTAL_DOUBLES ,SUM(TRIPLES) TOTAL_TRIPLES SUM(HR),TOTAL_HR
FROM TEAMSTATS
类似地 如果想找一下所有的点数在300 包括300 以上的的队员 则语句如下
输入/输出?:
SQL>SELECT SUM(SINGLES) TOTAL_SINGLES, SUM(DOUBLES) TOTAL_DOUBLES,
TOTAL_SINGLES 174
SUM(TRIPLES)
TOTAL_TRIPLES SUM(HR) TOTAL_HR
FROM
TEAMSTATS
WHERE HITS/AB >=.300
想估计一下一个球队的平均中球率
输入/输出:
SQL>SELECT SUM(HITS)/SUM(AB) TEAM_AVERAGE FROM TEAMSTATS
SUM只能处理数字 如果它的处理目标不是数字 你将会收到如下信息
输入/输出:
SQL>SELECT SUM(NAME) FROM TEAMSTATS;
ERROR
ORA-01722 invalid number
no rows selected
该错误信息当然的合理的 因为NAME字段是无法进行汇总的
AVG
AVG可以返回某一列的平均值 如果你想知道漏球的平均数请看下例
输入:
SQL>SELECT AVG(SO) AVE_STRIKE_OUTS FROM TEAMSTATS
输出:
下边的例子反映了 SUM 与 AVG 的不同之处
输入/输出:
SQL>SELECT AVG(HITS/AB) TEAM_AVERAGE FROM TEAMSTATS
?
分析
可是在上一个例子中的打中率是.3370629 这是怎么回事呢 AVG 计算的是打中的次
数与总打击次数商的平均值 然而在上一个例子中是对打中次数和打击次数分别求和后在 进行相除的 举例来说 A 队员打了 100 杆 中了 50 次 那么他的平均值是 0.5 B 队员 打了1杆 没打中 他的平均值是0.0 而0.0与0.5的平均值是0.25 如果你按打101杆 中50杆计算 那么结果就会是正确的了 下边的例子将会返回正确的击中率
输入/输出:
SQL>SELECT AVG(HITS)/AVG(AB) TEAM_AVERAGE FROM TEAMSTATS
?
与 SUM 函数一样 AVG 函数也只能对数字进行计算
MAX
如果你想知道某一列中的最大值 请使用MAX 例如 你想知道谁的打点最高
输入:
SQL>SELECT MAX(HITS) FROM TEAMSTATS
输出:
你能从这里知道是谁打的最多吗
输入/输出:
SQL>SELECT NAME FROM TEAMSTATS WHERE HITS=MAX HITS
ERROR at line 3
ORA-00934
group function is not allowed here
很不幸 你不能 这一信息提示你汇总函数无法在 WHERE 子句中使用 但是请别灰心? ?深入 SELECT 语句 将引入子查询的概念并会给出知道谁是打 点最多人解决方案
如果把它用的非数字场合会有什么情况出现呢
输入/输出:
SQL>SELECT MAX(NAME) FROM TEAMSTATS
?
这是一个新现象 MAX 返回了最高的字符串 (最大的是 z )所以说 MAX 既可以处理数值也可以处理字符
MIN
MIN 与 MAX 类似 它返回一列中的最小数值 例如 你想知道打杆的最小值是多少
输入:
SQL>SELECT MIN(AB) FROM TEAMSTATS
输出:
下列语句将返回名字在字母表中排在最前边的
输入/输出?:
SQL>SELECT MIN(NAME) FROM TEAMSTATS
你可以同时使用MAX和MIN函数以获得数值的界限 例如
输入/输出:
SQL>SELECT MIN(AB), MAX(AB) FROM TEAMSTATS
?
对于统计函数来说这一信息有时非常有用
注 我们在今天开始曾说过 这五个函数是由 ANSI 标准所定义的 其余的函数也已 经成为了事实上的标准 你可以在所有的 SQL 解释器中找到它们 这里 我们使用的它们 在ORACLE7中的名字 在其它的解释器中它们的名称可能与这里提到的不同
VARIANCE
VARIANCE 方差 不是标准中所定义的 但它却是统计领域中的一个至关重要的数 值 使用方法如下
输入:
SQL>SELECT VARIANCE HITS FROM TEAMSTATS
输出:
如果我们在将它应用于字符串
输入/输出:
SQL>SELECT VARIANCE NAME FROM TEAMSTATS
ERROR
ORA-01722 invalid number
No rows selected
可见 VARIANCE也是一个只应用于数值对象的函数
STDDEV
这是最后一个统计函数 STDDEV返回某一列数值的标准差 它的应用示例如下:
SQL>SELECT STDDEV HITS FROM TEAMSTATS
输入:
SQL>SELECT STDDEV HITS FROM TEAMSTATS
输出:
同样 对字符型列应用该函数时会得到错误信息
输入/输出?:
SQL>SELECT STDDEV(NAME) FROM TEAMSTATS
ERROR:
ORA-01722: invalid number
no rows selected
这些统计函数也可以在一个语句中同时使用
输入/输出?:
SQL>SELECT COUNT(AB),AVG(AB),MIN(AB),MAX(AB) ,STDDEV(AB) ,VARIANCE(AB) ,SUM(AB) FROM TEAMSTATS
当你下次见到比赛结果时 你应该知道了SQL正在它的后台工作
三、日期/时间函数
我们的生活是由日期和时间来掌握的 大多数的 SQL 解释器都提供了对它进行支持的 函数 在这一部分我们使用PROJECT表来演求日期和时间函数的用法
输入:
SQL> SELECT * FROM PROJECT
?输出:
注 这里的数据类型使用日期型 大多数 SQL 解释器都有日期型 但是在语法的细则 上有不同之处
ADD_MONTHS
该函数的功能是将给定的日期增加一个月 举例来说 由于一些特殊的原因 上述的 计划需要推迟两个月 那么可以用下面的方法来重新生成一个日程表
输入:
SQL>SELECT TASK ,STARTDATE ENDDATE
ORIGINAL_END ,ADD_MONTHS(ENDDATE,2) FROM PROJECT
输出:
尽管这种延误不太可能发生 但是实现日程的变动却是非常容易的 ADD_MONTHS 也可能工作在SELECT之外 试着输入:
输入:
SQL>SELECT TASK TASKS_SHORTER_THAN_ONE_MONTH
FROM PROJECT WHERE ADD_MONTHS(STARTDATE,1) >ENDDATE
结果如下所示
输出:
分析:
你将会发现这一部分中的几乎所有的函数都可能工作在不只一个地方 但是 如果没有 TO_CHAR 和 TO_DATE 函数的帮助 ADD_MONTH 就无法在字符或数字类型中工作 这将在今天的晚些时候讨论
LAST_DAY
LAST_DAY可以返回指定月份的最后一天 例如 如果你想知道在ENDDATE列中的 给出日期中月份的最后一天是几号时 你可以输入
输入:
SQL>SELECT ENDDATE, LAST_DAY ENDDATE FROM PROJECT
结果如下:
输出?:
如果是在闰年的最后一天呢
输入/输出:
SQL>SELECT LAST_DAY( '1-FEB-95 ') NON_LEAP ,LAST_DAY( '1-FEB-96' )
LEAP FROM PROJECT;
?
分析:
结果当然是正确的 可是为什么它输出了这么多行呢 这是因为你没有指定任何列或 给出一个条件 SQL 引擎对数据库中的每一条记录都应用了这一语句 如果你想去掉这些 重复的内容可以这样写
输入:
SQL>SELECT DISTINCT LAST_DAY('1-FEB-95') NON_LEAP ,LAST_DAY('1-FEB-96')
LEAP FROM PROJECT
在这句话中我们使用了关键字 DISTINCT 参见第二天的 介绍查询 — — SELECT 语 句的使用 来得到唯一的结果
输出:
虽然在我的电脑上该函数可以正确地识别出闰年来 但是如果你要将它应用于金融领 域 那么请在你的解释器上试一下 看一看它是否支持闰年
MONTHS_BETWEEN
如果你想知道在给定的两个日期中有多少个月 可以像这样来使用MONTHS_BETWEEN
输入:
SQL>select task,startdate ,enddate,months between(Startdate,enddate) duration
from project
输出:
请等一下 结果看起来不太对劲 再试一下:
输入/输出?:
SQL> SELECT TASK STARTDATE ENDDATE,MONTHS_BETWEEN ENDDATE,STARTDATE DURATION FROM PROJECT
分析:
如你所见 MONTHS_BETWEEN 对于你所给出的月份的次序是敏感的 月份值为负数可能并不是一件坏事 例如 你可以利用负值来判断某一日期是否在另一个日期之前 下例将会显示所有在 1995 年 5 月 19 日以前开始的比赛
输入:
SQL>SELECT * FROM PROJECT
WHERE MONTHS_BETWEEN ('19 MAY 95',STARTDATE)>0
输出:
NEW_TIME
如果你想把时间调整到你所在的时区 你可以使用 NEW_TIME 下边给出了所有的时 区
?
你可以这样来调节时间:
输入:
SQL>SELECT ENDDATE EDT ,NEW_TIME(ENDDATE, 'EDT','PDT') FROM PROJECT
输出:
?就像变魔术一样 所有的时间和日期都变成以新的时区标准了
NEXT_DAY
NEXT_DAY 将返回与指定日期在同一个星期或之后一个星期内的 你所要求的星期天 数的确切日期 如果你想知道你所指定的日期的星期五是几号 可以这样做
输入:
SQL>SELECT STARTDATE NEXT_DAY(STARTDATE ,'PROJECT') FROM
FRIDAY
返回结果如下:
输出:
分析:
输出的结果告诉了你距你所指定的日期最近的星期五的日期
SYSDATE
SYSDATE 将返回系统的日期和时间
输入:
SQL> SELECT DISTINCT SYSDATE FROM PROJECT
?输出:
SYSDATE
18-JUN-95 1020PM
如果你想知道在今天你都已经启动了哪些项目的话 你可以输入:
输入/输出:
SQL>SELECT * FROM PROJECT WHERE STARTDATE SYSDATE
?现在 你已经看到了项目在今天所启动的部分
四、数学函数
大多数情况下你所检索到的数据在使用时需要用到数学函数 大多数 SQL 的解释器都 提供了与这里相类似的一些数学函数 这里的例子使用的表名字叫NUMBERS 内容如下
输入:
SQL>SELECT * FROM NUMBERS
输出:
ABS
ABS 函数返回给定数字的绝对值 例如
输入:
SQL>SELECT ABS(A) ABSOLUTE_VALUE FROM NUMBERS 输出
?输出:
CEIL 和FLOOR
CEIL 返回与给定参数相等或比给定参数在的最小整数 FLOOR 则正好相反 它返回 与给定参数相等或比给定参数小的最大整数 例如
输入:
SQL>SELECT B, CEIL(B) CEILING FROM NUMBERS
输出:
输入/输出:
SQL>SELECT A ,FLOOR(A) FLOOR FROM NUMBERS
?
COS、 COSH 、SIN 、SINH、 TAN、 TANH
COS SIN TAN 函数可以返回给定参数的三角函数值 默认的参数认定为弧度制 如果你没有认识到这一点那你会觉得下例所返回的值是错误
输入:
SQL>SELECT A,COS(A)FROM NUMBERS
?输出:
分析:
你可能认为 COS(45 )的返回值应该为 0.707 左右 ,而不应该是 0.525 如果你想让它按照弧度制来计算 那么你需要将弧度制转换成角度制 由于360角度为2个弧度 所以我们可以写成:
输入/输出:
SQL>SELECT A, COS (A*0.01745329251994) FROM NUMBERS
分析:
这里的将角度转换成弧度后的数值 三角函数也可以像下面所写的那样工作 :
输入/输出:
SQL>SELECT A COS(A*0.017453), COSH(A*0.017453) FROM NUMBERS
输入/输出:
SQL>SELECT A, SIN(A*0.017453), SINH (A*0.017453) FROM NUMBERS
输入/输出:
SQL>SELECT A, TAN( A*0.017453 ),TANH(A*0.017453 )FROM NUMBERS
EXP
EXP将会返回以给定的参数为指数 以e为底数的幂值 其应用见下例:
输入:
SQL>SELECT A, EXP(A) FROM NUMBERS
?输出:
LN and LOG
这是两个对数函数 其中LN返回给定参数的自然对数 例如
输入?:
SQL>SELECT A ,LN(A) FROM NUMBERS
输出:
ERROR
ORA-01428 argument ‘-45’ is out of range
这是因为我们忽视了参数的取值范围 负数是没有对数的 改写为?:
输入/输出:
SQL>SELECT A ,LN ((ABS A )) FROM NUMBERS
分析:
注意 你可以将 ABS 函数嵌入到 LN 函数中使用 第二个对数函数需要两个参数 其中第二个参数为底数 下例将返回以10为底的B列的对数值
输入/输出:
SQL>SELECT B ,LOG(B ,10) FROM NUMBERS
MOD
其实我们已经见过 MOD 函数了 在第三天的 表达式 条件及操作 就有它 我们 知道在ANSI标准中规定取模运算的符号为%在一些解释器中被函数MOD所取代 下例的 查询就返回了 A 与 B 相除后的余数
输入:
SQL>SELECT A, B, MOD (A ,B) FROM NUMBERS
?输出:
POWER
该函数可以返回某一个数对另一个数的幂 在使用幂函数时 第一个参数为底数 第 二个指数
输入:
SQL>SELECT A ,B, POWER(A, B ) FROM NUMBERS
输出:
ERROR:
ORA-01428: argument '45' is out of range
分析:
粗看时你可能会认为它不允许第一个参数为负数 但这个印象是错误的 因为像-4 这 样的数是可以做为底数的 可是 如果第一个参数为负数的话 那么第二个参数就必须是 整数 负数是不能开方的 对于这个问题可以使用CEIL 或FLOOR 函数
输入:
SQL>SELECT A, CEIL (B ),POWER (A, CEIL(B)) FROM NUMBERS
输出:
现在就可以有正确的结果了
SIGN
如果参数的值为负数 那么 SIGN 返回-1 如果参数的值为正数 那么 SIGN 返回 1 如果参数为零 那么SIGN也返回零 请看下例:
输入:
SQL>SELECT A SIGN(A) FROM NUMBERS
输出:
你也可以在 SELECT WHERE 子句中使用 SIGN
输入:
SQL>SELECT A FROM NUMBERS WHERE SIGN(A) =1
输出:
SQRT
该函数返回参数的平方根 由于负数是不能开平方的 所以我们不能将该函数应用于负数
输入/输出:
SQL>SELECT A,SQRT(A) FROM NUMBERS ERROR
ORA-01428: argument '-45' is out of range
但是你可以使用绝对值来解除这一限制
输入/输出:
SQL>SELECT ABS(A),SQRT(ABS (A)) FROM NUMBERS
五、字符函数
许多 SQL 解释器都提供了字符和字符串的处理功能 本部分覆盖了大部分字符串处理 函数 这一部分的例子使用CHARACTERS表
输入/输出:
SQL> SELECT * FROM CHARACTERS
CHR
该函数返回与所给数值参数等当的字符 返回的字符取决于数据库所依赖的字符集 例如示例的数据库采用了ASCLL字符集 示例数据库的代码列的内容为数字
输入:
SQL>SELECT CODE, CHR (CODE) FROM CHARACTERS
输出:
在数值32处显示为空白 因为32在ASCLL码表中是空格
CONCAT
我们在第 3 天时学到过一个与这个函数所执行的功能相当的操作 符号表示将两个字符串连接起来 CONCAT 也是完成这个功能的 使用方法如下
输入:
SQL>SELECT CONCAT(FIRSTNAME,LASTNAME) "FIRST AND LAST NAMES"
FROM CHARACTERS
?输出:
分析:
当用多个词来做为别名时需对它们使用引号 请检查你的解释器 看看它是否支持别名,需要注意的是尽管在看起来输出似乎是两列 但实际上它仍是一列 这是因为你所连接的 Firstname 字段的宽度为 15 函数取得了该列中的所有数据 包括其中用以补足宽度 的空格
INITCAP
该函数将参数的第一个字母变为大写 此外其它的字母则转换成小写
输入:
SQL>SELECT FIRSTNAME BEFORE ,INITCAP(FIRSTNAME) AFTER
FROM CHARACTERS
输出:
LOWER 和 UPPER
如你所料 LOWER将参数转换为全部小写字母而UPPER则把参数全部转换成大写字母
下例是用 LOWER 函数和一个叫 UPDATE 的函数来把数据库的内容转变为小写字母
输入:
SQL>UPDATE CHARACTERS SET FIRSTNAME='kelly'
WHERE FIRSTNAME='KELLY'
?输出:
1 row updated.
输入:
SQL>SELECT FIRSTNAME FROM CHARACTERS
输出:
然后 请您再输入:
SQL>SELECT FIRSTNAME UPPER (FIRSTNAME), LOWER(FIRSTNAME) FROM CHARACTERS
?输出:
?现在你明白这两个函数的作用了吧
LPAD 与 RPAD
这两个函数最少需要两个参数 最多需要三个参数 每一个参数是需要处理的字符串 第二个参数是需要将字符串扩充的宽度 第三个参数表示加宽部分用什么字符来做填补 第三个参数的默认值为空格 但也可以是单个的字符或字符串 下面的句子中向字段中加 入了五个字符 该字段的定义宽度为 5
输入:
SQL>SELECT LASTNAME,LPAD(LASTNAME ,20,'*') FROM CHARACTERS
输出:
分析:
为什么只添加了5个占位字符呢 不要忘记LASTNAME列是15个字符宽 在可见字符的右方填充着空格以保证字符的定义宽度 请检查一下你所用的解释器 现在再试一下 右扩充
输入:
SQL>SELECT LASTNAME RPAD(LASTNAME ,20,'*') FROM CHARACTERS
输出:
?
分析:
通过这个操作我们可以清楚地看到空格也是该字段内容的一部分这一事实了 下边的两个函数正是用于这一情况的
LTRIM 与 RTRIM
LTRIM 和 RTRIM 至少需要一个参数 最多允许两个参数 第一个参数与 LPAD 和 RPAD 类似 是一个字符串 第二个参数也是一个字符或字符串 默认则是空格 如果第二个参 数不是空格的话 那么该函数将会像剪除空格那样剪除所指定的字符 如下例
输入:
SQL> SELECT LASTNAME RTRIM(LASTNAME) FROM CHARACTERS
输出:
你可以用下边的语句来确认字符中的空格已经被剪除了
输入:
SQL> SELECT LASTNAME RPAD(RTRIM(LASTNAME), 20 , '*') FROM CHARACTERS
输出:
?
输出证明的确已经进行了剪除工作 现在请再试一个LTRIM
输入:
SQL>SELECT LASTNAME, LTRIM (LASTNAME ,'C') FROM CHARACTERS
输出:
注意 第三行和第五行的 已经没有了
REPLACE
它的工作就如果它的名字所说的那样 该函数需要三个参数 第一个参数是需要搜索 的字符串 第二个参数是搜索的内容 第三个参数则是需要替换成的字符串 如果第三个 参数省略或者是NULL 那么将只执行搜索操作而不会替换任何内容
输入:
SQL> SELECT LASTNAME,REPLACE(LASTNAME,'ST') REPLACEMENT FROM CHARACTERS
输出:
如果存在第三个参数 如么在每一个目标字符串中搜索到的内容将会被由第三个参数所指 定的字符串替换 例如
输入:
SQL> SELECT LASTNAME,REPLACE(LASTNAME, 'ST ','**') REPLACEMENT
FROM CHARACTERS
输出:
?
如果没有第二个参数 那么只有将源字符串返回而不会执行任何操作
输入?:
SQL> SELECT LASTNAME, REPLACE(LASTNAME,NULL) REPLACEMENT
FROM CHARACTERS
输出:
SUBSTR
这个函数有三个参数 允许你将目标字符串的一部份输出 第一个参数为目标字符串 第二个字符串是将要输出的子串的起点 第三个参数是将要输出的子串的长度
输入:
SQL>SELECT FIRSTNAME, SUBSTR(FIRSTNAME,2,3) FROM CHARACTERS
?输出:
如果第二个参数为负数 那么将会从源串的尾部开始向前定位至负数的绝对值的位置 例 如
输入:
SQL>SELECT FIRSTNAME, SUBSTR(FIRSTNAME, -13, 2) FROM CHARACTERS
输出:
?
分析:
切记FIRSTNAME字段的宽度为15 这也就是为什么参数为-13时会从第三个开始的原因 因为从 15 算起向前算第 13 个字符正好是第 3 个字符 如果没有第三个参数 将会输出字 符串余下的部分
输入:
SQL>SELECT FIRSTNAME, SUBSTR(FIRSTNAME,3) FROM CHARACTERS
?输出:
看 是不是将字符串余下的部分返回了 现在再来看一个例子
输入:
SQL> SELECT * FROM SSN_TABLE
输出:
?
如果直接阅读上边的结果是比较困难的 比较好的解决办法是使用下划线 请先想一下下 边语句的输出情况
输入:
SQL> SELECT SUBSTR( SSN,1,3) ||'-'||SUBSTR(SSN,4 ,2 )||'-'||SUBSTR(SSN,6,4)
SSN FROM SSN_TABLE
输出:
?
注 这在当数字特别大 例如 1 343 178 128 需要用逗号分隔时以及区位号码或电 话号码需要下划线分隔时特别有效
这是 SUBSTR 的另一个非常有用的功能 倘若你需要打印一个报表而其中一些列的宽度超 过了 50 个字符时 你可以使用 SUBSTR 来减小列宽以使它更接近数据的真实宽度 请看 一个下面的这两个例子
输入:
SQL> SELECT NAME , JOB DEPARTMENT FROM JOB_TBL
输出:
NAME______________________________________________________________ JOB_______________________________DEPARTMENT______________________ ALVIN SMITH
VICEPRESIDENT MARKETING
1 ROW SELECTED.
分析:
注意 这几列已经换行显示了 这例得阅读变行非常困难 现在试一下下边的 SELECT语句
输入:
SQL> SELECT SUBSTR(NAME, 1,15) NAME, SUBSTR(JOB,1,15) JOB,DEPARTMENT
2 FROM JOB_TBL;
?输出:
NAME________________JOB_______________DEPARTMENT_____ ALVIN SMITH VICEPRESIDENT MARKETING
是不是变得好多了
TRANSLATE
这一函数有三个参数 目标字符串 源字符串和目的字符串 在目标字符串与源字符 串中均出现的字符将会被替换成对应的目的字符串的字符
输入:
SQL> SELECT FIRSTNAME, TRANSLATE(FIRSTNAME
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
'NNNNNNNNNNAAAAAAAAAAAAAAAAAAAAAAAAAA) FROM CHARACTERS
输出:
?注意 这个函数对大小写是敏感的
INSTR
如果需要知道在一个字符串中满足特定的内容的位置可以使用 INSTR 它的第一个参 数是目标字符串 第二个参数是匹配的内容 第三和第四个参数是数字 用以指定开始搜索的起点以及指出第几个满足条件的将会被返回 下例将从字符串的第二个字符开始 搜 索并返回第一个以 O 开头的字符的位置
输入:
SQL>SELECT LASTNAME,INSTR(LASTNAME,'O',2,1) FROM CHARACTERS
?输出:
分析:
默认第三个与第四个参数的数值均为 如果第三个数值为负数 那么将会从后向前搜索
LENGTH
LENGTH将返回指定字符串的长度 例如
输入:
SQL>SELECT FIRSTNAME,LENGTH(RTRIM(FIRSTNAME)) FROM CHARACTERS
输出:
注意 :这里使用了函数RTRIM 否则LENGTH将全部返回15
六、转换函数
转换函数有三个 可以使你方便地将数据从一种类型变换为另一种类型 本节的示例
使用表 CONVERSIONS
输入:
SQL> SELECT * FROM CONVERSIONS
输出:
NAME列为字符串 该列的宽度为15 TESTNUM列为数字
TO_CHAR
该函数的最初功能是将一个数字转换为字符型 不同的解释器可能会使用它来转换其它的 数据类型 例如日期型转换为字符型或者是拥有更多的参数 下例展示了该函数的基本功 能
输入:
SQL> SELECT TESTNUM,TO_CHAR(TESTNUM) FROM CONVERT
输出:
稍安勿燥 下例可以证明它确实已经将TESTNUM转换为字符型了
输入:
SQL>SELECT TESTNUM,LENGTH(TO_CHAR(TESTNUM)) FROM CONVERT
输出:
分析:
如果对数字使用LENGTH函数将会返回错误 注意TO_CHAR与在先前进过的CHR不同
CHR 返回字符集中给定数字位置的一个字符或符号
TO_NUMBER
该函数与 TO_CHAR 函数相对应 显而易见 它是将一个字符串型数字转换为数值型 例 如
输入:
SQL> SELECT NAME,TESTNUM,TESTNUM*TO_NUMBER(NAME)FROM CONVERT
输出:
分析:
如果该函数没有将 NAME 转换为数值的话将会返回一个错误信息
七、其它函数
这里有三个函数可能对你是有用处的
GREATEST与LEAST
这两个函数将返回几个表达式中最大的和最小的 例如
输入:
SQL> SELECT GREATEST('ALPHA', 'BRAVO', 'FOXTROT', 'DELTA') FROM CONVERT
输出:
分析:
注意GREATEST将会返回在字母表中最靠后的字符开头的字符串 虽然看起来似乎没有必要使用 FROM 子句 可是如果 FROM 子句没有的话 你将会收到一个错误信息 每 一个SELECT语句都需要FROM子句 由于给定的表有三行 所以结果返回了三个
输入:
SQL>SELECT LEAST(34, 567, 3 ,45, 1090) FROM CONVERT
输出:
就像你看到的那样 这两个函数也可以对数字进行处理
USER
该函数返回当前使用数据库的用户的名字
输入:
SQL> SELECT USER FROM CONVERT
输出:
只有我一个人在使用这个数据库 看 SELECT 又一次对表中的每一行都返回了结果 该函数与在今天早些时候提及的日期函数类似 甚至尽管 USER 不是表中确实存在的列 但 SELECT 仍然检索了表中的每一行
八、问与答
问 :为什么在 ANSI 标准中定义的函数这么少, 而不同的解释器又都定义了这么多的函数?
答 :ANSI 标准是一个非常宽松的标准 而且如果对所有的解释器生产厂家来说过多的限 制会使其走向破产的道路 另一方面 如果 A 公司对 SQL 补充了一个用于统计的函数包而销路特别好的话 那么B公司和C公司一定也会跟着做的。
问 :我认为你对SQL的介绍太简单了 ,我的工作时应该如何去使用这些函数呢?
答 这个问题与一个都三角的教师所提出的问题类似 事实上我也不知道如何却求一个等腰三角形的面积 所以 我的回答是 根据你的职业而定 你的工作中需要用到哪些 函数你就去使用它 而其它的对你来说则是没有必要掌握的 这一观点也适用于你的 查询。
九、校练场
1 哪个函数是用来将给定字符串的第一个字母变成大写而把其它的字符变成小写的
答:函数名为 ucfirst()
,它是用来将给定字符串的第一个字母变成大写而把其它的字符变成小写的函数。
2 哪此函数的功能就如同它的名字含义一样
答:SQL中有很多函数的名字和功能都和它的名字含义一样,以下是一些例子:
- CONCAT:将多个字符串连接成一个字符串。
- UPPER:将字符串转换为大写。
- LOWER:将字符串转换为小写。
- TRIM:去除字符串开头和结尾的空格。
- LENGTH:返回字符串的长度。
- REPLACE:替换字符串中的某个子字符串。
- SUBSTRING:截取字符串的一部分。
- ROUND:将数字四舍五入。
- CEILING:向上取整。
- FLOOR:向下取整。
3 下边的查询将如何工作
SQL> SELECT COUNT(LASTNAME) FROM CHARACTERS;
答:这个查询将返回一个数字,该数字表示“CHARACTERS”表中有多少行包含非空“LASTNAME”列。查询将计算这些行的数量,并作为结果返回。
4 下边的查询是干什么的
SQL> SELECT SUM(LASTNAME) FROM CHARACTERS;
答:这个查询语句是用来计算 CHARACTERS
表中 LASTNAME
列的所有值的总和。
SELECT SUM(LASTNAME)
:这部分表示要从表中选择?LASTNAME
?列的值,并对其进行求和计算。FROM CHARACTERS
:这部分指定了要从名为?CHARACTERS
?的表中进行查询。
请注意,这只是一个示例查询语句,具体的结果取决于您的数据库中的实际数据。如果 LASTNAME
列包含数字类型的值,则可以通过该查询获取它们的总和。但是,如果 LASTNAME
列包含字符串类型的值,则该查询将会报错。
5 哪个函数可以将FIRSTNAME列与LASTNAME列合并到一起
答:在SQL中,可以使用CONCAT函数将两个列合并为一个列。例如,可以使用以下代码将FIRSTNAME和LASTNAME列合并到一个名为FULLNAME的新列中:
SELECT CONCAT(FIRSTNAME, ' ', LASTNAME) AS FULLNAME FROM table_name;
在这里,使用空格将FIRSTNAME和LASTNAME隔开,以便在FULLNAME列中创建一个格式化的名称。
6 在下边的查询中 ,6是什么意思
输入:
SQL> SELECT COUNT(*) FROM TEAMSTATS;
输出:
COUNT(*)
6
答:在此查询中,数字 6 表示 TEAMSTATS 表中有 6 行数据。查询结果是计算 TEAMSTATS 表中所有记录的总数。
7 下列语句将输出什么
SQL> SELECT SUBSTR(LASTNAME,1,5) FROM NAME_TBL;
答:该语句将从名为 NAME_TBL 的表中选择 LASTNAME 字段的前五个字符,并将结果输出。
十、练习
1 用今天的 TEAMSTARTS 表来写一个查询 用来显示谁的中球率低于 0.25 (中球率 的计算方法为 hits/ab)
答:
假设 TEAMSTARTS 表中有以下字段:
- player_id: 球员唯一标识符
- ab: 打数
- hits: 安打数
则可以使用以下 SQL 查询来显示中球率低于 0.25 的球员:
SELECT player_id, hits/ab as batting_average
FROM TEAMSTARTS
WHERE hits/ab < 0.25
该查询会返回符合条件的球员的唯一标识符和中球率,按中球率从小到大排序。
2 用今天的CHARACTERS表来写一个查询 要求返回下边的结果 INITIALS__________CODE
K.A.P.? ? ? 32? ? ??1 row selected.
答:以下是查询语句:
SELECT
CONCAT(SUBSTR(first_name, 1, 1), '.', SUBSTR(last_name, 1, 1), '.', SUBSTR(nickname, 1, 1), '.') AS INITIALS,
code AS CODE
FROM
CHARACTERS
WHERE
first_name = 'Kenny' AND
last_name = 'McCormick' AND
nickname = 'Princess'
LIMIT 1;
查询结果:
INITIALS | CODE
--------------|-----
K.A.P. | 32
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!