MySQL必知必會十一:使用數據處理函數

11.1 函數

SQL支持利用函數來處理數據。函數一般是在數據上執行的,它給數據的轉換和處理提供了方便。

函數沒有SQL的可移植性強:能運行在多個系統上的代碼稱爲可移植的( portable)。相對來說,多數SQL語句是可移植的,在SQL實現之間有差異時,這些差異通常不那麼難處理。而函數的可移植性卻不強。幾乎每種主要的DBMS的實現都支持其他實現不支持的函數,而且有時差異還很大。爲了代碼的可移植,許多SQL程序員不贊成使用特殊實現的功能。雖然這樣做很有好處,但不總是利於應用程序的性能。如果不使用這些函數,編寫某些應用程序代碼會很艱難。必須利用其他方法來實現DBMS非常有效地完成的工作。如果你決定使用函數,應該保證做好代碼註釋,以便以後你(或其他人)能確切地知道所編寫SQL代碼的含義。

11.2 使用函數

大多數SQL實現支持以下類型的函數。
用於處理文本串(如刪除或填充值,轉換值爲大寫或小寫)的文本函數。

  • 用於在數值數據上進行算術操作(如返回絕對值,進行代數運算)
    的數值函數。
  • 用於處理日期和時間值並從這些值中提取特定成分(例如,返回
    兩個日期之差,檢查日期有效性等)的日期和時間函數。
  • 返回DBMS正使用的特殊信息(如返回用戶登錄信息,檢查版本
    細節)的系統函數。

11.2.1 文本處理函數

我們已經看過一個文本處理函數的例子,其中使用RTrim()函數來去除列值右邊的空格。下面是另一個例子,這次使用Upper()函數:

mysql> SELECT vend_name, Upper(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name;
+----------------+------------------+
| vend_name      | vend_name_upcase |
+----------------+------------------+
| ACME           | ACME             |
| Anvils R Us    | ANVILS R US      |
| Furball Inc.   | FURBALL INC.     |
| Jet Set        | JET SET          |
| Jouets Et Ours | JOUETS ET OURS   |
| LT Supplies    | LT SUPPLIES      |
+----------------+------------------+
  • 分析:正如所見, Upper()將文本轉換爲大寫,因此本例子中每個供應商都列出兩次,第一次爲vendors表中存儲的值,第二次作爲列vend_name_upcase轉換爲大寫。
函 數 說 明
Left() 返回串左邊的字符
Length() 返回串的長度
Locate() 找出串的一個子串
Lower() 將串轉換爲小寫
LTrim() 去掉串左邊的空格
Right() 返回串右邊的字符
RTrim() 去掉串右邊的空格
Soundex() 返回串的SOUNDEX值
SubString() 返回子串的字符
Upper() 將串轉換爲大寫

11.2.2 日期和時間處理函數

函 數 說 明
AddDate() 增加一個日期(天、周等)
AddTime() 增加一個時間(時、分等)
CurDate() 返回當前日期
CurTime() 返回當前時間
Date() 返回日期時間的日期部分
DateDiff() 計算兩個日期之差
Date_Add() 高度靈活的日期運算函數
Date_Format() 返回一個格式化的日期或時間串
Day() 返回一個日期的天數部分
DayOfWeek() 對於一個日期,返回對應的星期幾
Hour() 返回一個時間的小時部分
Minute() 返回一個時間的分鐘部分
Month() 返回一個日期的月份部分
Now() 返回當前日期和時間
Second() 返回一個時間的秒部分
Time() 返回一個日期時間的時間部分
Year() 返回一個日期的年份部分

首先需要注意的是MySQL使用的日期格式。無論你什麼時候指定一個日期,不管是插入或更新表值還是用WHERE子句進行過濾,日期必須爲格式yyyy-mm-dd。因此, 2005年9月1日,給出爲2005-09-01。雖然其他的日期格式可能也行,但這是首選的日期格式,因爲它排除了多義性。

mysql> SELECT cust_id, order_num FROM orders WHERE order_date = '2005-09-01';
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
|   10001 |     20005 |
+---------+-----------+
  • 分析:此SELECT語句正常運行。它檢索出一個訂單記錄,該訂單記錄的order_date2005-09-01

Date(order_date)指示MySQL僅提取列的日期部分,更可靠的SELECT語句爲:

mysql> SELECT cust_id, order_num FROM orders WHERE Date(order_date) = '2005-09-01';
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
|   10001 |     20005 |
+---------+-----------+

如果要的是日期,請使用Date():如果你想要的僅是日期,則使用Date()是一個良好的習慣,即使你知道相應的列只包含日期也是如此。這樣,如果由於某種原因表中以後有日期和時間值,你的SQL代碼也不用改變。當然,也存在一個Time()函數,在你只想要時間時應該使用它。

如果你想檢索出2005年9月下的所有訂單,怎麼辦?簡單的相等測試不行,因爲它也要匹配月份中的天數。有幾種解決辦法,其中之一如下所示:

mysql> SELECT cust_id, order_num FROM orders WHERE Date(order_date) BETWEEN '2005-09-01' AND '2005-09-30';
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
|   10001 |     20005 |
|   10003 |     20006 |
|   10004 |     20007 |
+---------+-----------+
  • 分析:其中, BETWEEN操作符用來把2005-09-01和2005-09-30定義爲一個要匹配的日期範圍。

還有另外一種辦法(一種不需要記住每個月中有多少天或不需要操心閏年2月的辦法):

mysql> SELECT cust_id, order_num FROM orders WHERE Year(order_date)=2005 AND Month(order_date)=9;
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
|   10001 |     20005 |
|   10003 |     20006 |
|   10004 |     20007 |
+---------+-----------+
  • 分析:Year()是一個從日期(或日期時間)中返回年份的函數。類似,Month()從日期中返回月份。因此, WHERE Year(order_date)= 2005 AND Month(order_date) = 9檢索出order_date爲2005年9月的所有行。

11.2.3 數值處理函數

函 數 說 明
Abs() 返回一個數的絕對值
Cos() 返回一個角度的餘弦
Exp() 返回一個數的指數值
Mod() 返回除操作的餘數
Pi() 返回圓周率
Rand() 返回一個隨機數
Sin() 返回一個角度的正弦
Sqrt() 返回一個數的平方根
Tan() 返回一個角度的正切
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章