第7课 创建计算字段
存储在数据库中的数据一般不是应用程序所需要的格式,我们需要直接从数据库中检索出转换、计算或格式化的数据,而不只是检索出数据,然后再去客户端应用程序中重新格式化。计算字段并不实际存在于数据库表中,计算字段时运行时再select语句内创建的。
字段(field)基本上于列(column) 的意思相同,经常互换使用,不过数据库列一般称为列,而字段这个属于通常在计算字段这种场合下使用。
一、拼接字段
拼接(concatenate)将值联结在一起(将一个值附加到另一个值)构成单个值。
1、案例介绍,vendors表中包含供应商名和地址信息,假如要生成一个供应商报表,需要在格式化的名称(位置)中列出供应商的位置。此报表需要一个值,而表中数据存储在两个列vend _name和vend_country中,此外,需要用括号vend_country括起来,这些东西都没有存储在数据库表中。可使用操作符(+)或两个竖杠(||)表示。
输入:select vend_name + '(' + vend_country + ')' from vendors order by vend_name;
输入:select vend_name || '(' || vend_country || ')' from vendors order by vend_name;
输入:select contact(vend_name , '(' ,vend_country,')') from vendors order by vend_name;
分析:上面的select语句拼接以下元素
- 存储在vend_name列中的名字
- 包含一个空格和一个左圆括号的字符串
-存储在vend_country列中的国家 - 包含一个右圆括号的字符串
语句返回的是结合成一个计算字段的两个列用空格填充,而实际上你要的结果不需要这些空格,可以使用rtrim()函数来完成,该函数用来去掉左右两边的所有空格,通过使用此函数,各个列都进行了整理。
输入:select rtrim(vend_name) + '(' + rtrim(vend_country) + ')' from vendors order by vend_name;
输入:select rtrim(vend_name) || '(' || rtrim(vend_country) || ')' from vendors order by vend_name;
二、使用别名,有时也叫导出列(derived column)。新计算列的只是一个值,如果仅在sql查询工具中查看以下结果,这样没什么不好,但是,一个未命名的列不能用于客户端应用中,因为客户端没有办法引用它。别名(alias)是一个字段或值的替换名。别名用as关键字赋予。
输入:select rtrim(vend_name) + '(' + rtrim(vend_country) + ')' as vend_title from vendors order by vend_name;
输入:select rtrim(vend_name) || '(' || rtrim(vend_country) || ')' as vend_title from vendors order by vend_name;
输入:select contact(vend_name , '(' ,vend_country,')') as vend_title from vendors order by vend_name;
as指定计算结果的名为vend_title,任何客户端应用都可以按名称引用这个列,就像它是一个实际的表列一样。as也可用于在实际的表列名包含不合法的字符(如空格)时重新命名它,在原来的名字含混或容易误解时扩充它。
三、执行算术计算
计算字段的另一个常见用途是对检索出的数据进行算数计算。
案例:orders表包含收到的所有订单,orderitems表包含每个订单中的各项物品。下面的sql语句检索订单号20008中的所有物品。
输入:select prod_id, quantity, item_price from orderitems where order_num = 20008;
输入:select prod_id, quantity, item_price, quantityitem_price as expanded_price from orderitems where order_num = 20008;
输出中显示expanded_price 列是一个计算字段,此计算为quantity item_price。客户端应用现在可以使用这个新计算列,就像使用其它列一样。sql支持的算数操作符包括+-*/,圆括号可以用来区分优先顺序
如何测算数据?select语句为测试、检验函数和计算提供了很好的方法,但是省略了from子句后就是简单地访问和处理表达式。
第8课 使用函数处理数据
与大多数计算机语言一样,sql也可以用函数来处理数据,函数一般是再数据上执行的,为数据的转换和处理提供方便。几乎所有的DBMS都同等地支持sql语句,单但每一个dbms都有特定的函数,每个函数的名称和语法可能及其不同。
可移植(portable):所编写的代码可以在多个系统上运行。为了代码的可移植,许多sql程序员不赞成使用特定于实现的功能。如果你决定使用函数,应该保证做好代码注释,以便以后你自己(或他人)能确切地知道这些sql代码的含义。
一、文本处理函数(用于处理文本字符串,如删除或填充值,转换值为大写或小写)的文本函数
输入:select vend_name,upper(vend_name) as vend_name_upcase from vendors order by vend_name;
分析:upper()将文本转换成大写,因此本例中每个供应商都列出两次,第一次为vendors表中存储的值,第二次作为列vend_name_upcase转换为大些。
常用的文本处理函数
left()(或使用子字符串函数)。 返回字符串左边的字符
length()(也使用datalength()或len())返回字符串的长度
lower() 将字符串转换为小写
ltrim() 去掉字符串左边的空格
right()(或使用字符串函数) 返回字符串右边的字符
rtrim() 去掉字符串右边的空格
substr() 或substring() 提取字符串的组成部分
soundex() 返回字符串的soundex值,是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。考虑了类似的发音音符和音节,使得能对字符串进行发音比较而不是字母比较
输入:select cust_name,cust_contact from customers where soundex(cust_contact)=soundex('Michael green');(他匹配到所有发音类似于Michael green)
二、日期或事件处理函数
输入:select order_num from orders where datepart(yy,order_date)=2020;
datepart()函数,此函数返回日期的某一部分,有两个参数,它们分别是返回的成分和从中返回成分的日期。datepart()只从order_date列中返回年份,通过与2020比较,where子句只过滤此年份的订单。
输入:select order_num from orders where date_part('year',order_date)=2020;
输入:select order_num from orders where extract(year from order_date)=2020;
extract()函数用来提取日期成分,year 表示提取哪个部分,返回值再与2020进行比较
输入:select order_num from orders where order_date between to_date('2020-01-01','yyyy-mm-dd')and to_date('2020-12-31','yyyy-mm-dd')
输入:select order_num from orders where year(order_date)=2020;
输入:select order_num from orders where strftime('%y',order_date)='2020';
三、数值处理函数
abs() 返回一个数的绝对值
cos()返回一个角度的余弦
exp()返回一个数的指数值
pi()返回圆周率派的值
sin()返回一个角度的正弦
sqrt()返回一个数的平方根
tan()返回一个角度的正切
第9课 汇总数据
聚集函数(aggregate function),对某些行运行的函数,计算并返回一个值,用来汇总表的数据,我们经常汇总数据,而不用把它们实际检索出来。
1、AVG()函数,通过对表中行数计数并计算其列值之和,求得该列的平均值。可用来返回所有列的平均值,也可用来返回特定列或行的平均值。
输入:select avg(prod_price)as avg_price from products;(返回包含products表中所有产品的平均价格)
输入:select avg(prod_price)as avg_price from products where vend_id ='dll01';(where子句用来过滤除vend_id为dll01的产品,因此只返回该供应商产品的平均值),avg()函数忽略值为null的行
2、count()函数,用来确定表中行的数目或者符合特定条件的行的数目。首先,使用count()对表中行的数据进行计算,不管表列中包含的是空值(null)还是非空值;其次,使用count(column)对特定列中具有值的行进行计数,忽略null值。
输入:select count()as num_cust from customers;(利用count()对所有行计数,不管行中各列有什么值,计数值在num_cust中返回)
输入:select count(cust_email)as num_cust from customers;(使用count(cust_email)对cust_email列中有值的行进行计数)
针对null值,如果指定列名,则count()函数会忽略指定列的值为null的行,但如果count()函数中用的是星号(),则不忽略
3、max()函数,返回指定列中的最大值,要求指定列名
输入:select max(prod_price)as max_price from products;(max()返回products表中最贵物品的价格)
注:一般用来找出最大的数值或日期值,但许多dbms允许将它返回任意列中的最大值,包括返回文本列中的最大值。在用于文本数据时,max()返回按该列排序的最后一行。忽略值为null的行
4、min()函数,返回指定列的最小值,与max()一样,min()要求指定列名
输入:select min(prod_price) as min_price from products;(返回products表中最便宜物品的价格,其余的注意事项与max类似)
5、sum()函数,返回指定列值的和(总计)。orderitems包含订单中实际的物品,每个物品都相应的数量。可如下检索所订物品的总数(所有quantity值之和)
输入:select sun(quantity) as items_ordered from orderitems where order_num =20005;(sum()返回订单中所有物品数量之和,where子句保证只统计某个物品订单中的物品)
输入:select sum(item_price*quantity) as total_price from orderitems where order_num =20005;(用来合计计算值,得出总的订单金额,where子句保证只统计某个物品订单中的物品)
sumI()函数忽略值为null的行。
二、聚集不同值
以上5个聚集函数都可以如下使用
- 对所有行执行计算,指定all参数或不指定参数(因为all时默认行为)
- 只包含不同的值,指定distinct参数
提示:all为默认值,不需要指定。如果不指定distinct,则假定为all。
输入:select avg(distinct prod_price)as avg_price from products where vend_id='dll01';(在使用distinct后,此例中的avg_price比较高,因为有多个物品具有相同的较低的价格。排除它们提升了平均价格)
注意:distinct只能用于count()必须使用列名,不能用于计算或表达式,但不能用于count()
三、组合聚集函数
select语句可根据需要包含多个聚集函数
输入:select count() as num_items,min(prod_price) as price_min, max(prod_price) as price_max,avg(prod_price) as price_avg from products;(这里用单挑select语句执行了4个聚集计算,返回4个值)
注意:取别名,在指定别名以包含某个聚集函数的结果时,不应该使用表中实际的列名。
网友评论