在前面几篇博文中已经介绍了许多与表有关的操作。为了演示SQL的不同组件,前面讨论了创建表、基于表的视图、查询表、修改表的数据以及表的关系等。在接下来的博文中将继续介绍SQL中的函数和表达式的使用,重点学习SQL编程人员最常用到的内容。应当注意的是,下面介绍的函数和表达式仅仅是SQL所支持的多种函数和表达式的一部分。
另外,SQL的实现方式以及支持的SQL函数和表达式,除了标准函数外,不同产品还有一些一些非标准的函数。我们可以通过查询相关产品文档来了解其功能和特性。
一.行函数
1. 简介
行函数会在表中单独某个行的基础上计算新值。这个新值可以基于一个列中的数据或者是基于几个不同列的中的数据。一些行函数职能用于数字,而另外一些行函数可以用于文本或者日期。
行函数计算或者构造了一个原表中没有的新值。这个新值是从原始表的一个或者多个单元的数值中构造出来的。所有这些值都必须是表中某个 单独行的一部分。
举例来说,创建一个“出库明细1”表,它的数据来自“出库单明细表”。在新表中,通过使用行函数创建一个新的列,这个列将“出库单价”列和“出库数量”列的积组合在一起构成了另一个名为“商品总额”的列,并且在新表中不显示商品的出库数量:
SELECT 出库单编号,商品编号,出库单价,出库单价*出库数量 AS 商品总额
INTO 出库明细1
FROM 出库单明细表信息
仍以此数据库为例,出库单明细表中列出:出库单编号、商品编号、出库单价和商品总额。通过将出库单价和出库数量的积来计算商品总额,并且按照商品总额列对结果排序,只列出总额大于20000的出库信息:
SELECT 出库单编号,商品编号,出库单价,(出库单价*出库数量) AS 商品总额
FROM 出库单明细信息
WHERE (出库单价*出库数量)>20000
ORDER BY (出库单价*出库数量)
值得注意的是,在使用行函数构造新列时,如果其中一个值为NULL,那么新列的值也为NULL。
2.分类
下面对常见行函数进行分类介绍,包括数学函数、文本函数和日期函数。
2.1 数学函数
一些行函数可以在数字上执行算术运算,而其它一些函数可以对数字进行四舍五入或者舍位运算。用于算术运算符的行函数可以执行各种运算。正如在大多数的计算机语言中那样,星号被用作乘号;NULL并不等于零,它可以表示一个未知数据。因此,所有对NULL进行操作的行函数都会产生一个NULL作为结果。
SQL的符号标志函数的执行过程是:如果值为正,结果为1;如果值为0,结果为0;如果值为负,结果为-1;如果值为NULL,结果为NULL。
举例来说,我们要计算10和26的乘积。则可以使用下面的语句进行计算:
SELECT 10*26 FROM TEMP
又如,测试X除以3以后的余数,X代表从0~9之间的所有数字被存储在N1表中,则执行下面的语句即可测得结果:
SELECT N,N MOD 3 AS 'N MOD 3' FROM NI ORDER BY
2.2 文本函数
行函数也可以用于文本,大多数行函数会生成一些输出文本,但是少数行函数会返回一些数字。
下面举例来说,我们将所在城市和地址合并到一个单列中,并在城市之间添加两个空格分割。首先选择珠宝商的“所在城市”列,然后在城市的右边添加两个空格,再选择“珠宝商地址”列。下面的语句是在“珠宝营销系统”数据库的“珠宝商信息”表中列出北京市的珠宝商信息,要求显示珠宝商的编号、姓名、电话和详细地址。详细地址为所在城市和四肢的组合,使用两个空格进行分隔。
SELECT 珠宝商编号,珠宝商姓名,电话,珠宝商所在城市+' '+珠宝商地址 as 北京市珠宝商地址
FROM 珠宝商信息
WHERE 珠宝商所在城市='北京市'
又如,在数据库“珠宝商营销”中,检索数据表“顾客信息”。计算消费者所在城市的字符串长度,并根据其长度获取字串。
SELECT 消费者姓名,消费者所在城市+消费者地址 AS 联系地址,居住城市=Substring(消费者所在城市,1,Len(消费者所在城市)-1),STR(消费者消费额) AS 消费金额
FROM 顾客信息
WHERE 消费者所在城市='南京市'
2.3 日期函数
日期函数的格式不同于日期格式,日期格式改变了日期的显示方式,但是没有改变它的值,而日期函数会更改日期的值是指成为一个新的日期。
通常,日期的计算是以天数为单位,而不是以月份或者年份为单位进行的,因为一个月中的天数或者一年中的天数变化可能很多。
如果直接将这些日期写入SELECT语句,则必须使用函数将引号内的文本字符串转换成日期函数数据类型。
下面介绍一个日期函数的例子。这个函数计算了出库日期到当前日期为止的年数,满12个月为1年。在这个例子,使用了SQL的GetDate()函数来取得当前日期。它完成了按出库日期进行排序,列出所有出库至今1年(包括1年)的信息。
SELECT 出库单编号,客户编号,库存编号,出库日期,操作员编号,操作日期
FROM 出库单信息
WHERE DATEDIFF(year,出库日期,getdate())>=1
ORDER BY 出库日期
二.列函数
在此前,结果表中的数据都是直接来自原表;使用行函数结果是原表某个行的结合。接下来。我们将介绍列行数,使用列行数结果表中的数据可以是原表整个列的数据的汇总。
1. 简介
表中的数据时使用列行数进行汇总的,列行数会检查列中的所有事护具,这涉及到表的每个行。这里的汇总是在结果表中的一个单行上进行的
列可以是一个行函数,也可以是存储在磁盘上的一个数据列。前面我们介绍过的任意行函数都可以创建一个新列,然后可以使用列行数对这个列进行操作。
汇总操作可以针对整个表的所有行,可能有几百行、几千行甚至更多。所有行中的数据都被汇总为一个数字、字符串或者日期。
列行数也被称为聚合函数或者组函数,每一个列函数都会产生一个不同类型的汇总。与行函数相比,列函数的数量只有很少几种。当然,在一些SQL产品中对列函数进行了扩展,定义了用于特殊目的的其他列函数。
2. 常见函数的使用
在了解了一些关于列函数的基本知识后,我们来介绍一下一些常见的函数的使用。
2.1 MAX函数和MIN函数
通过使用MAX和MIN函数,显示它们对在文本、数字和日期数据类型的3种列总的应用。
列的数据类型决定了应用于其数据的排序顺序:文本列按照字母顺序进行排序,数字列按照数字顺序进行排序,日期列按照日期属性进行排序。这些排序都有可能影响最大值和最小值的选择。
使用GROUP BY子句将产生多个数值的结果,而不使用GROUP BY子句时,整个表就是一个组。通常,在使用列函数时不用GROUP BY自己,因此结果只有一个行。在结果集中,每一个列都是单独进行计算的,结果表中的行包含一些彼此可能并不能紧密相关的列。
当在包含一列函数的查询中使用WHERE子句时,WHERE子句先得到处理,然后只对满足WHERE条件时的行使用列函数,而不是对表中的所有事数据都使用列函数。
举例来说,从“珠宝营销系统”数据库按珠宝商所在城市进行分组,查找符合以下条件的珠宝商信息:
截止日期在2003年一年的珠宝商;所有珠宝商信息中最小的成本百分比;珠宝商的最高珠宝售价;按姓名排序最末位的珠宝商姓名。
SELECT MAX(珠宝商姓名) AS 姓名,
MIN(成分百分比) AS 成分百分比,
MAX(珠宝售价) AS 珠宝售价,
MAX(截止日期) AS 截止日期,珠宝商所在城市
FROM 珠宝商信息
WHERE 截止日期 BETWEEN '2003-1-1' AND '2003-12-30'
GROUP BY 珠宝商所在城市
2.2 COUNT函数
COUNT函数用来计算表中记录的个数或者列中值得个数,计算的内容有SELECT语句来指定。使用CONUT函数时,必须指定一个列名称或者使用星号,星号表示极端一个表中所有记录。例如,如果要知道“操作人员”表中有多少记录,可以使用如下SELECT语句:
SELECT COUNT(*) AS 操作员总数 FROM 操作人员
这个语句中COUNT函数的参数是星号,表示返回“操作人员”表中的所有记录。返回值列在“操作员总数”列下面,“操作员总数”指定一个字段的别名,用来存储返回的查询结果。
SQL中有两种不同的方法来对列中的数据计数。这两种方法的不同之处在于它们处理NULL的方式不同:COUNT(*)函数计算了表中所有行的数量,COUNT(colunmn)函数统计了特定列中的数量,并且忽略了所有的NULL,即对指定列中不为NULL的所有数值进行函数,返回列中有多少数据。
如果想知道特定列中值得个数而不是表中记录的个数,可以使用列名代替星号。例如,修改上面的例子中的SELECT语句,计算“操作人员姓名”列中的值得个数:
SELECT COUNT(操作人员姓名) AS 操作人员总数 FROM 操作人员信息
如果要考虑重复值得出现的情况,即有可能出现相同的操作人员姓名的情况,这时可在COUNT函数中加上DISTINCT关键字:
SELECT COUNT(DISTINCT 操作人员姓名) AS 操作人员总数 FROM 操作人员信息
2.3 SUM函数
该函数只能应用于数字列,不能对文本和日期类型上的列进行计算。
SUM函数用于对值求和。使用它可以很方便地对分组数据计算总和。和其他列函数一样们如果数据没有明确指定分组,SUM函数将把整个表看作一组,在对列进行相加时将忽略NULL。
在本例中,从”出库单明细信息“表中计算商品出库的总计数,出库商品的总数量和出库商品总金额信息。总数量是”出库数量“列值的总和,总金额是”出库商品金额“列值得总和。
SELECT COUNT(出库单编号) AS 出库计数,SUM(出库数量) AS 出库总数量,
SUM(出库商品金额) AS 出库商品总金额
FROM 出库单明细信息
在SELECT语句中使用列函数COUNT(column)对表中所有的行进行计数,SUM(column)函数对指定的列进行求和运算。
2.4 AVG函数
最后介绍一个列函数时AVG(),它用来计算包含在特定查询字段中的一组数值的算术平均值。和SUM一样,在计算不包括任何NULL,该函数只能应用于数字列,不能对文本和日期类型上的列i进行计算。
同样以”销售管理系统“的”出库单明细信息“表为例介绍,使用AVG()函数计算平均出库量、平均商品金额和平均出库单价。语句如下:
SELECT COUNT(出库单编号) AS 出库计数,AVG(出库数量) AS 平均出库量,
AVG(出库商品金额) AS 平均商品金额,AVG(出库单价) AS 平均出库单价
FROM 出库单明细信息
在上述语句的基础上,我们将使用列函数对结果进行分组和汇总,并用WHERE子句限定查询的范围。查询出在2002年09月15日至2002年09月18日之间,商品的发票汇总信息,然后再对结果进行按日期分组。这些汇总信息有:按规定日期内开出发票的数量,使用发票的消费者中最大的编号,对该段日期内的发票小计求和,发票价格的平均税收,发票金额的总和以及总利润:
SELECT COUNT(发票编号) AS 发票数,MAX(消费者编号) AS 最大消费者编号,
SUM(发票小计) AS 发票小计汇总,
AVG(税收) AS 平均税收,SUM(总计) AS 金额总计,SUM(利润) AS 总利润
FROM 发票信息
WHERE 开发票日期 BETWEEN '2002-09-15' AND '2002-09-18'
GROUP BY 开发票日期
三.表达式
1.简介
表达式是用来返回一个数值的表达式,表达式中包含列名、数值、数学运算符、关键字,或者其他元素组成的公式或返回单个值得表达式。例如,可以将两个列的数值合并生成一个新的值,或者对一个列的数值进行操作生成一个新的值。
2. 数值表达式
数值表达式是使用数学运算符来计算存储在表中的数值类型的数值类型的数据。在数值表达式中可以用运算符对数据进行加、减、乘、除运算。
建立数值表达式和建立数学公式一样,它们的基本运算规则相同。例如,乘和除的运算优先高于加和减,可以使用括号改变运算的顺序,即被括号括住的部分先进行计算,然后再与表达式的其他部分运算。
为了更清楚地理解数值表达式,现在来看一些数值表达式的示例。在数据库”经销商“中,查询表”销售信息“,并计算出商品的单价。
SELECT 商品编号,销售数量,金额,(金额/销售数量) AS 销售单价
FROM 销售信息
数值表达式不仅能用SELECT子句中,还可以用在WHERE子句中来指定搜索条件。仍以上述例子为基础,现在作如下修改:要求返回销售单价大于500的商品。
USE 销售管理系统
GO
SELECT 商品编号,销售数量,金额,(金额/销售数量) AS 销售单价
FROM 销售信息
WHERE (金额/销售数量) >500
3. CASE表达式
CASE表达式是能建立一系列修改SQL语句返回特定值的条件表达式。CASE表达式可以改变值的表示方法或者生成一个新值。每个值都根据CASE表达式中的条件进行修改。CASE表达式是由CASE关键字和一些条件组成。如果前面所有条件都不满足,则最后一个条件为默认条件;表达式结束时要用关键字END。CASE表达式有两种形式:简单表达式和选择表达式,这两种形式都支持ELSE默认条件,且可以相互转换。
下面介绍一个示例。在数据库”销售管理系统“中,查询”操作人员信息“表,列出其中的操作人员姓名、电话信息,并以文本的形式列出各操作人员是否具有出库权限:
USE 销售管理系统
GO
SELECT 操作人员姓名,联系电话,
CASE 出库权限
WHERE 1 THEN '具有'
WHEN 0 THEN '不具有'
ELSE '错误'
END AS 是否具有出库权限
FROM 操作人员信息
又如,在数据库”销售管理系统“中的”收入明细信息“表,根据收入金额判断销售任务是否完成。完成情况。完成情况为:超过50000以上为超额完成任务,50000以下10000以上为完成任务,所有少于10000位未完成任务:
USE 销售管理系统
GO
SELECT 出库单编号,收入金额,完成情况=
CASE
WHEN 收入金额>50000 THEN '超额完成'
WHEN 收入金额>10000 THEN '完成任务'
ELSE '未完成'
END
FROM 收入明细信息
下面举一个CASE表达式在SET子句中的应用的例子:在数据库”销售管理系统“中,修改”输入明细信息“表的盈利金额列。要求:盈利金额大于等于3000,则调整为原盈利金额加100;盈利金额大于2000(含2000)小雨3000,则调整为原盈利金额加50;其他情况不变:
USE 销售管理系统
GO
UPDATE 收入明细信息
SET 盈利金额=
CASE
WHEN 盈利金额>=3000 THEN 盈利金额+100
WHEN 盈利金额>=2000 THEN 盈利金额+50
ELSE 盈利金额
END
4. CAST表达式
CAST表达式的功能和CASE表达式的功能有很大不同。当从数据库中得到一个值时,CAST表达式可以改变值的数据类型。但是不能改变源数据的数据类型。当对数据库中的列值进行运算时,如果要进行运算的列值类型不相匹配,这时就可用CAST表达式进行数据类型的转换。
使用CAST表达式,必须依次指定CAST关键字,在括号中指定列名、AS关键字和新的数据类型。
例如,在数据库”销售管理系统“中,检索数据表”收入明细信息”,将其中的收入金额一以文本形式列出来:
USE 销售管理系统
GO
SELECT 出库单编号,收入金额,盈利金额,
CAST(收入金额 AS CHAR(10)) AS 收入金额的文本形式
FROM 收入明细信息
四.学习小结
从个人来说,自己先后整理了SQL的这些知识,感觉收获真的是很大,先前也学习过一些关于这些的知识,但是却很是不够理解自己先前的一些知识,但是经过这次整理后,有一种守得云开见月明的感觉,很是爽。自己也会在数据库中,努力去尝试的练习,把这些知识努力都做到严格的整理和实际化。
对于函数和表达式的使用,在这里我们就大概的介绍这些,希望这些经过整理过的较系统的知识能够可以帮我和大家更好地了解和学习这方面的知识。在接下来的日子里,依然将是写这方面的整理知识,期待吧!