创建计算字段
这一课介绍什么是计算字段,如何创建计算字段,以及如何从应用程序 中使用别名引用它们。
7.1计算字段
存储在数据库表中的数据一般不是应用程序所需要的格式,下面举几个 例子。
口需要显示公司名,同时还需要显示公司的地址,但这两个信息存储在
不同的表列中。
口城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签打
印程序需要把它们作为一个有恰当格式的字段检索出来。
口列数据是大小写混合的,但报表程序需要把所有数据按大写表示出来。 口物品订单表存储物品的价格和数量,不存储每个物品的总价格(用价
格乘以数量即可)。但为打印,需要物品的总价格。
口需要根据表数据进行诸如总数、平均数的计算。
在上述每个例子中,存储在表中的数据都不是应用程序所需要的。我们 需要直接从数据库中检索出转换、计算或格式化过的数据,而不是检索
出数据,然后再在客户端应用程序中重新格式化。
7.2拼接字段丨55 这就是计算字段可以派上用场的地方了。与前几课介绍的列不同,计算 字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句内 创建的。
字段(field)
基本上与列(column)的意思相同,经常互换使用,不过数据库列一 般称为列,而术语字段通常与计算字段一起使用。
需要特别注意,只有数据库知道SELECT语句中哪些列是实际的表列,
哪些列是计算字段。从客户端(如应用程序)来看,计算字段的数据与 其他列的数据的返回方式相同。
在SQL语句内可完成的许多转换和格式化工作都可以直接在客户端
应用程序内完成。但一般来说,在数据库服务器上完成这些操作比在 客户端中完成要快得多。
7.2拼接字段
为了说明如何使用计算字段,我们来举一个简单例子,创建由两列组成 的标题。
Vendors表包含供应商名和地址信息。假如要生成一个供应商报表,需 要在格式化的名称(位置)中列出供应商的位置。
此报表需要一个值,而表中数据存储在两个列vend_name和vend_ country中。此外,需要用括号将vend_country括起来,这些东西都 没有存储在数据库表中。这个返回供应商名称和地址的SELECT语句很
简单,但我们是如何创建这个组合值的呢?
拼接(concatenate)
将值联结到一起(将一个值附加到另一个值)构成单个值。
解决办法是把两个列拼接起来。在SQL中的SELECT语句中,可使用一
个特殊的操作符来拼接两个列。根据你所使用的DBMS,此操作符可用 加号(+)或两个竖杠(II)表示。在MySQL和MariaDB中,必须使用 特殊的函数。
说明:是+还是I I?
Access 和 SQL Server使用 +号。DB2、Oracle、PostgreSQL、SQLite 和 Open Office Base使用| | o详细请参阅具体的DBMS文档。
下面是使用加号的例子(多数DBMS使用这种语法):
输入▼
SELECT
vend_name + ' (' + vend_countey + ')'
FROMVendons
ORDER
BY vend_name;
输出▼
|
Bear Emporium |
(USA |
) |
|
Bears R Us |
(USA |
) |
|
Doi 1 House Inc. |
(USA |
) |
|
Fun and Games |
(England |
) |
|
Furbal1 Inc. |
(USA |
) |
|
Jouets et ours |
(France |
) |
下面是相同的语句,但使用的是丨I语法:
输入▼
SELECT vend_name || * (' || vend_country
|| ')
FROM
Vendors
ORDER
BY vend_name;
输出▼
|
|
||
|
Bea。Emporium |
(USA |
) |
|
Beans R Us |
(USA |
) |
|
Do】】 House Inc. |
(USA |
) |
|
Fun and Games |
(England |
) |
|
Furbal1 Inc. |
(USA |
) |
|
Jouets eV oues |
(France |
) |
下面是使用MySQL或MariaDB时需要使用的语句:
输入▼
SELECT
Concat(vend_name, * (', vend_country,')')
FROM
Vendoms
ORDER
BY vend_name;
分析▼
上面两个SELECT语句拼接以下元素:
口存储在vend_name列中的名字;
口包含一个空格和一个左圆括号的字符串;
口存储在vencLcountry列中的国家;
□包含一个右圆括号的字符串。
从上述输出中可以看到,SELECT语句返回包含上述四个元素的一个列
(计算字段)。
再看看上述SELECT语句返回的输出。结合成一个计算字段的两个列用 空格填充。许多数据库(不是所有)保存填充为列宽的文本值,而实际 上你要的结果不需要这些空格。为正确返回格式化的数据,必须去掉这
些空格。这可以使用SQL的RTRIMC)函数来完成,如下所示:
输入▼
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country)
+ ')
FROM Vendors
ORDER BY vend_name;
输出▼
Bear Emporium (USA)
Bears R Us (USA)
Doi 1 House Inc. (USA)
Fun and Games (England)
FunbalR Inc. (USA)
Jouets et ours (France)
下面是相同的语句,但使用的是I I :
输入▼
SELECT RTRIM(vend_name) || * (* || RTRIM(vend_country)
|| ')
FROM Vendors
ORDER BY vend_name;
输出▼
Bear Emporium (USA)
Bears R Us (USA)
Doi 1 House Inc. (USA)
Fun and Games (England)
Furbal1 Inc. (USA)
Jouets et ours (France)
分析▼
RTRIMO函数去掉值右边的所有空格。通过使用RTRIMO,各个列都进 行了整理。
说明:TRIM函数
大多数DBMS都支持RTRIMC)(正如刚才所见,它去掉字符串右边的
空格)、LTRIMO (去掉字符串左边的空格)以及TRIMO (去掉字符 串左右两边的空格)。
使用别名
从前面的输出可以看到,SELECT语有可以很好地拼接地址字段。但是, 这个新计算列的名字是什么呢?实际上它没有名字,它只是一个值。如
果仅在SQL查询工具中查看一下结果,这样没有什么不好。但是,一个 未命名的列不能用于客户端应用中,因为客户端没有办法引用它。
为了解决这个问题,SQL支持列别名。别名(alias)是一个字段或值的
替换名。别名用AS关键字赋予。请看下面的SELECT语句:
输入▼
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ,)'
AS vend_title
FROM Vendors
ORDER BY veocLname;
输出▼
vend_title
Bear Emporium (USA)
Bears R Us (USA)
Doi 1 House Inc. (USA)
Fun and Games (England)
Furbal1 Inc. (USA)
Jouets et ours (France)
下面是相同的语句,但使用的是丨I语法:
输入▼
SELECT RTRIM(vend_name) || ' (' || RTRIM(vend_country) || ')
AS vend_title
FROM Vend。ms
ORDER BY vend_name;
下面是MySQL和Mark^B中使用的语句:
输入▼
SELECT Concat(vend_name, ' (', vend_country, ))
AS vend_title
FROMVendons
ORDER BYvencLname;
分析▼
SELECT语句本身与以前使用的相同,只不过这里的计算字段之后踉了文 本ASvend_titie。它指示SQL创建一个包含指定计算结果的名为 vend_title的计算字段。从输出可以看到,结果与以前的相同,但现
在列名为vencLtitle,任何客户端应用都可以按名称引用这个列,就像 它是一个实际的表列一样。
说明:AS通當可选
在很多DBMS中,AS关键字是可选的,不过最好使用它,这被视为 一条最佳实践图
提示:别名的其他用途
别名还有其他用途。常见的用途包括在实际的表列名包含不合法的字
符(如空格)时重新命名它,在原来的名字含混或容易误解时扩充它。
别名的名字既可以是一个单词,也可以是一个字符串。如果是后者,
字符串应该括在引号中。虽然这种做法是合法的,但不建议这么去做。 多单词的名字可读性高,不过会给客户端应用带来各种问题。因此, 别名最常见的使用是将多个单词的列名重命名为一个单词的名字。
别名有时也称为导出列(derived column),不管怎么叫,它们所代表 的是相同的东西。
7.3执行算术计算
计算字段的另一常见用途是对检索出的数据进行算术计算。举个例子, Orders表包含收到的所有订单,Orderitems表包含每个订单中的各项 物品。下面的SQL语句检索订单号20008中的所有物品:
输入▼
SELECT prod_id, quantity, item_price
FROM OrderItems
WHERE order_num = 20008;
|
输出▼ |
||
|
prod_i d |
quantity |
item_price |
|
RGAN01 |
5 |
4.9900 |
|
BR03 |
5 |
11.9900 |
|
BNBG01 |
10 |
3.4900 |
|
BNBG02 |
10 |
3.4900 |
|
BNBG03 |
10 |
3.4900 |
item_price列包含订单中每项物品的单价。如下汇总物品的价格(单
价乘以订购数量):
输入▼
SELECT
procLid,
quantity,
ce,
q u an t i ty*-itein_p n 1 ce AS expanded_pri ce
nPOP
OadeaPtams
p p E RE
a a d a n_ n n m = p 0 0 p p ;
输出▼
|
p「od_id |
quantity |
ce |
expanded_price |
|
RGANO1 |
5 |
4.9900 |
24.9500 |
|
BRO3 |
5 |
11.9900 |
59.9500 |
|
BNBGO1 |
10 |
3.4900 |
34.9000 |
|
BNBGO2 |
10 |
3.4900 |
34.9000 |
|
BNBGO3 |
10 |
3.4900 |
34.9000 |
|
分析▼ |
|
|
|
输出中显示的expandecLprice列是一个计算字段,此计算为quantity- item_priceo客户端应用现在可以使用这个新计算列,就像使用其他列 一样。
SQL支持表7.1中列出的基本算术操作符。此外,圆括号可用来区分优
先顺序。关于优先顺序的介绍,请参阅第5课。
|
表7-1 SQL算术操作符 |
|
|
操作符 |
说 明 |
|
+ |
加 |
|
. |
减 |
|
* |
乘 |
|
/ |
除 |
SELECT语句为测试、检验函数和计算提供了很好的方法。虽然SELECT 通常用于从表中检索数据,但是省略了
FROM子句后就是简单地访问和
处理表达式,例如 SELECT 3 * 2;将返回 6, SELECT Trim(' abc 将返回abc,
SELECT Now();使用Now()函数返回当前日期和时间。
现在你明白了,可以根据需要使用SELECT语句进行检验。
7.4小结
这一课介绍了计算字段以及如何创建计算字段。我们用例子说明了计算 字段在字符串拼接和算术计算中的用途。此外,还讲述了如何创建和使
用别名,以便应用程序能引用计算字段。




