函数
与其他大多数计算机语言一样,SQL支持利用函数来处理数据。
在前一章中用来去掉串尾空格的RTrim()
就是一个函数的例子。
文本处理函数
SELECT vend_name, Upper(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name;
常用的文本处理函数如下:
示例:
Left
SELECT vend_name, Left(vend_name,3) AS vend_name_upcase FROM vendors ORDER BY vend_name;
Right
SELECT Right('test123',4) AS testLocate;
Length
SELECT vend_name, Length(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name;
Locate
SELECT LOCATE('bar', 'foobarbar') AS testLocate;
注,Locate接受2个参数or3个参数。
如果接受两个参数,则第一个参数是子串,第二个参数是母串。返回子串在母串中的位置。(下标从1开始)
如果接受3个参数。则第一个参数是子串,第二个参数是母串。第三个参数是查找母串中第参数个位置及之后的位置。但返回的依旧是在母串中的总体位置。
SELECT LOCATE('bar', 'foobarbar',7) AS testLocate;
如果找不到,就返回0.
SELECT LOCATE('bar', 'foobarbar',8) AS testLocate;
Lower
将所有的大写英文字母变成小写。
SELECT Lower('TEST123一') AS testLocate;
Upper
SELECT Upper('test123') AS testLocate;
把所有的小写英文字母变成大写。
LTrim
SELECT LTrim(' asd') AS testLocate;
右边是RTrim, 两端是Trim, 就不演示了。
SubString
substring的玩法还挺多的。
你可以给2个参数,也可以给3个参数。
也就是说,第三个参数,即子串最大长度是可选的。
第一个参数代表要处理的串,第二个参数代表子串的起始位置(可以是正数也可以是负数,但不可以是0, 是0的话查出来是个空串,没有意义)。
正数的话代表从字符串的第args个位置往后取子串。取多少? 如果没有第3个参数,就取到末尾。 如果有,就取max(第3个参数,remains_length)那么长。
负数的话,代表从倒数第abs(args)个位置开始取。
SELECT SubString('asdf',2,100) AS testLocate;
SELECT SubString('asdf',-2,1) AS testLocate;
SELECT SubString('asdf',-2) AS testLocate;
SELECT SubString('asdf',2) AS testLocate;
Soundex
这个函数就更有意思了。
SOUNDEX是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX考虑了类似的发音字符和音节,使得能对串进行发音比较而不是字母比较。
下面给出一个使用Soundex()函数的例子。customers表中有一个顾客Coyote Inc.,其联系名为Y.Lee。但如果这是输入错误,此联系名实际应该是Y.Lie,怎么办?显然,按正确的联系名搜索不会返回数据,如下所示:
SELECT * FROM customers WHERE cust_contact='Y. Lie';
我们将他们都转换成soundex。
SELECT * FROM customers WHERE Soundex(cust_contact)=Soundex('Y. Lie');
卧槽神奇把。。我和我的小伙伴都TM惊呆了。
日期和时间处理函数
日期和时间采用相应的数据类型和特殊的格式存储,以便能快速和有效地排序或过滤,并且节省物理存储空间。
数据经常需要用日期进行过滤。用日期进行过滤需要注意一些别的问题和使用特殊的MySQL函数。
首先需要注意的是MySQL使用的日期格式。无论你什么时候指定一个日期,不管是插入或更新表值还是用WHERE
子句进行过滤,日期必须为格式yyyy-mm-dd
。
因此,2005年9月1日,给出为2005-09-01。
应该总是使用4位数字的年份
支持2位数字的年份,MySQL处理00-69为2000-2069,处理70-99为1970-1999。虽然它们可能是打算要的年份,但使用完整的4位数字年份更可靠,因为MySQL不必做出任何假定。
SELECT * FROM orders WHERE order_date='2005-09-01';
我们看一下orders的表结构:
DESC orders;
order_date的数据类型为datetime。这种类型存储日期及时间值。样例表中的值全都具有时间值00:00:00,但实际中很可能并不总是这样。如果用当前日期和时间存储订单日期(因此你不仅知道订单日期,还知道下订单当天的时间), 怎么办? 比如, 存储的order_date 值为2005-09-01 11:30:05,则WHERE order_date = '2005-09-01’失败。即使给出具有该日期的一行,也不会把它检索出来,因为WHERE匹配失败。
这种情况咋整?
解决办法是指示MySQL
仅将给出的日期与列中的日期部分进行比较,而不是将给出的日期与整个列值进行比较。为此,必须使用Date()
函数。Date(order_date)
指示MySQL
仅提取列的日期部分,更可靠的SELECT
语句为:
SELECT * FROM orders WHERE Date(order_date)='2005-09-01';
我们来做一下时间的实验,当然啦,只是举个栗子。
看一下表中的数据:
发现都没有时间,我们更新一下:
UPDATE orders SET order_date=Now() WHERE order_num=20005;
现在表变成了这个样子:
SELECT * FROM orders WHERE Time(order_date)='11:37:36';
还有一种日期比较需要说明。如果你想检索出2005年9月下的所有订单,怎么办?简单的相等测试不行,因为它也要匹配月份中的天数。有几种解决办法,其中之一如下所示:
SELECT * FROM orders WHERE Year(order_date)=2005 AND Month(order_date)=9;
另一种方法是:
SELECT * FROM orders WHERE Date(order_date) BETWEEN '2005-09-01' AND '2005-09-30';
其中,BETWEEN操作符用来把2005-09-01和2005-09-30定义为一个要匹配的日期范围。
数值处理函数
数值处理函数仅处理数值数据。