MySQL Reference Manual for version 4.1.0-alpha.


6.3 用於 SELECTWHERE 幾句的函數

一個 SQL 語句中的 select_expressionwhere_definition 可由任何使用了下面所描述函數的表達式組成。

包含 NULL 的表達式總是得出一個 NULL 值結果,除非表達式中的操作和函數在文件中有另外的說明。

注意:在一個函數名和跟隨它的括號之間必須不存在空格。這有助於 MySQL 語法分析程式區分函數調用和對恰巧與函數同名表或列的參照。然而,參數左右兩邊的空格卻是允許的。

你可以強制 MySQL 接受函數名後存在空格的形式,這需要通過以 --ansi 選項啟動 mysqld,或在 mysql_connect() 中使用 CLIENT_IGNORE_SPACE,但是,在這種情況下,所有的函數名均將成為保留字。查看章節 1.8.2 以 ANSI 樣式運行 MySQL.

為了簡潔,從 mysql 程式輸出的範例以縮寫的形式顯示。因此:

mysql> SELECT MOD(29,9);
1 rows in set (0.00 sec)

+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+

將被顯示為這樣:

mysql> SELECT MOD(29,9);
        -> 2

6.3.1 無類型的特殊運算幾和函數

6.3.1.1 圓括號

( ... )

括號,使用它來強制一個表達式的計算順序。

mysql> SELECT 1+2*3;
        -> 7
mysql> SELECT (1+2)*3;
        -> 9

6.3.1.2 比較運算幾

比較運算幾的結果是 1 (TRUE)、0 (FALSE) 或 NULL。這些函數可工作於數位和字串上。根據需要,字串將會自動地被轉換到數位,以及數位被轉換成字串(比如在 Perl 中)。

MySQL 使用下列規則進行比較:

預設地,字串使用目前字元集以忽略字母大小寫的方式進行比較(預設的字元集為 ISO-8859-1 Latin1,它對英語處理得很出色)。

下面的範例演示了對於比較操作字串到數位的轉換:

mysql> SELECT 1 > '6x';
         -> 0
mysql> SELECT 7 > '6x';
         -> 1
mysql> SELECT 0 > 'x6';
         -> 0
mysql> SELECT 0 = 'x6';
         -> 1
=
等於:
mysql> SELECT 1 = 0;
        -> 0
mysql> SELECT '0' = 0;
        -> 1
mysql> SELECT '0.0' = 0;
        -> 1
mysql> SELECT '0.01' = 0;
        -> 0
mysql> SELECT '.01' = 0.01;
        -> 1
<>
!=
不等於:
mysql> SELECT '.01' <> '0.01';
        -> 1
mysql> SELECT .01 <> '0.01';
        -> 0
mysql> SELECT 'zapp' <> 'zappp';
        -> 1
<=
小於或等於:
mysql> SELECT 0.1 <= 2;
        -> 1
<
小於:
mysql> SELECT 2 < 2;
        -> 0
>=
大於或等於:
mysql> SELECT 2 >= 2;
        -> 1
>
大於:
mysql> SELECT 2 > 2;
        -> 0
<=>
NULL 值安全等於:
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1 1 0
IS NULL
IS NOT NULL
測試一個值是或不是 NULL:
mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
        -> 0 0 1
mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
        -> 1 1 0
為了能夠與其它程式更好的工作,在使用 IS NULL 是 MySQL 支援下列額外選擇性:

expr BETWEEN min AND max
如果 expr 大於或等於 min ,並且 expr 小於或等於 maxBETWEEN 傳回 1,否則傳回 0。它等價於表達式 (min <= expr AND expr <= max) ,只要所有的參數均是相同的類型。 否則類型會依照上面的規則發生轉換,但是應用於所有三個參數。注意,在 MySQL 4.0.5 之前,參數被轉換到 expr 的類型。
mysql> SELECT 1 BETWEEN 2 AND 3;
        -> 0
mysql> SELECT 'b' BETWEEN 'a' AND 'c';
        -> 1
mysql> SELECT 2 BETWEEN 2 AND '3';
        -> 1
mysql> SELECT 2 BETWEEN 2 AND 'x-3';
        -> 0
expr NOT BETWEEN min AND max
等同於 NOT (expr BETWEEN min AND max)

expr IN (value,...)
如果 exprIN 清單中的作一值,它將傳回 1,否則傳回 0。如果所有的值均是常數,那麼所有的值被依照 expr 的類型進行計算和排序。然後以一個二進位搜尋方式完成項目的搜尋。這就意味著,如果 IN 清單完全由常陣列成,IN 將是非常快的。如果 expr 是一個字母大小寫敏感的字串表達式,字串比較將以大小寫敏感方式執行:
mysql> SELECT 2 IN (0,3,5,'wefwf');
        -> 0
mysql> SELECT 'wefwf' IN (0,3,5,'wefwf');
        -> 1
從 MySQL 4.1 開始(符合 SQL-99 標準),如果左手邊的表達式是 NULL,或者在清單中沒有發現相相符的值並且清單中的一個表達式是 NULLIN 均傳回 NULL

expr NOT IN (value,...)
等同於 NOT (expr IN (value,...))

ISNULL(expr)
如果 exprNULLISNULL() 傳回 1,否則傳回 0
mysql> SELECT ISNULL(1+1);
        -> 0
mysql> SELECT ISNULL(1/0);
        -> 1
注意,對 NULL 值使用 = 進行比較總是為 false !
COALESCE(list)
傳回清單中第一個非 NULL 的元素:
mysql> SELECT COALESCE(NULL,1);
        -> 1
mysql> SELECT COALESCE(NULL,NULL,NULL);
        -> NULL
INTERVAL(N,N1,N2,N3,...)
Returns 如果 N < N1 傳回 0,如果 N < N2 傳回 1,等等。所有的參數均被當作整數。為了函數能正確地工作,它要求 N1 < N2 < N3 < ... < Nn。這是因為它使用的是一個二進位的搜尋(非常地快):
mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
        -> 3
mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
        -> 2
mysql> SELECT INTERVAL(22, 23, 30, 44, 200);
        -> 0

如果以任何一個標準運算幾(=, <>..., 但除了 LIKE)對一個忽略大小寫的字串進行比較,尾部的空白空間(空格、TAB 和換行)均被忽略。

mysql> SELECT "a" ="A \n";
        -> 1

6.3.1.3 邏輯運算幾

在 SQL 中,所有的邏輯運算幾傳回的值均為 TRUE、FALSE 或 NULL (未知)。在 MySQL 中,它們由 1 (TRUE)、0 (FALSE) 和 NULL 實現。這些大部分在不同的 SQL 資料庫間是相同的,然而某些可能會以一個非零值傳回 TRUE。

NOT
!
邏輯非。 如果操作數為 0,傳回 1﹔如果操作數為非零,傳回 0﹔如果操作數為 NOT NULL,傳回 NULL
mysql> SELECT NOT 10;
        -> 0
mysql> SELECT NOT 0;
        -> 1
mysql> SELECT NOT NULL;
        -> NULL
mysql> SELECT ! (1+1);
        -> 0
mysql> SELECT ! 1+1;
        -> 1
最後一個範例傳回 1,因為表達式是與 (!1)+1 一樣被計算的。

AND
&&
邏輯與。 如果所有的操作數都是非零或非 NULL 的,傳回 1﹔如果有一個或多個操作數為 0 ,則傳回 0,只要操作數中有 NULL 傳回值就為 NULL
mysql> SELECT 1 && 1;
        -> 1
mysql> SELECT 1 && 0;
        -> 0
mysql> SELECT 1 && NULL;
        -> NULL
mysql> SELECT 0 && NULL;
        -> 0
mysql> SELECT NULL && 0;
        -> 0
請注意,在 MySQL 4.0.5 以前版本中,當遇到一個 NULL 時就停止計算,而不是繼續程序檢查可能存在的0。這就意味著,在這些版本中,SELECT (NULL AND 0) 傳回 NULL,而不是 0。在 4.0.5 中,代碼已被重新設計了,已便於在任何仍然使用最佳化情況下,傳回值總是能如 ANSI 所規定的那樣。
OR
||
邏輯或。 如果任何一個操作數是非零的,傳回值為 1,如果任一操作數為 NULL,傳回值為 NULL,否則傳回 0
mysql> SELECT 1 || 1;
        -> 1
mysql> SELECT 1 || 0;
        -> 1
mysql> SELECT 0 || 0;
        -> 0
mysql> SELECT 0 || NULL;
        -> NULL
mysql> SELECT 1 || NULL;
        -> 1
XOR
邏輯異或。 如果任一操作數為 NULL,傳回值為 NULL。對於非 NULL 的操作數,如果有奇數個非零的操作數,結果傳回為 1,否則傳回 0
mysql> SELECT 1 XOR 1;
        -> 0
mysql> SELECT 1 XOR 0;
        -> 1
mysql> SELECT 1 XOR NULL;
        -> NULL
mysql> SELECT 1 XOR 1 XOR 1;
        -> 1
a XOR b 算術相等於 (a AND (NOT b)) OR ((NOT a) and b)XOR 在 MySQL 4.0.2 中被加入。

6.3.1.4 控制流函數

IFNULL(expr1,expr2)
如果 expr1 為非 NULL 的,IFNULL() 傳回 expr1,否則傳回 expr2IFNULL() 傳回一個數位或字串值,這取決於它被使用的語境:
mysql> SELECT IFNULL(1,0);
        -> 1
mysql> SELECT IFNULL(NULL,10);
        -> 10
mysql> SELECT IFNULL(1/0,10);
        -> 10
mysql> SELECT IFNULL(1/0,'yes');
        -> 'yes'
在 MySQL 4.0.6 和更新版本中,IFNULL(expr1,expr2) 的預設傳回值以 STRINGREALINTEGER 順序更加'general'了兩個表達式。當你基於一個表達式建立一個表或在一個臨時表中 MySQL 不得不儲存一個從 IFNULL() 傳回的值時,這個與較早 MySQL 版本的不同將更加值得注意。
CREATE TABLE foo SELECT IFNULL(1,"test") as test;
在 MySQL 4.0.6 中,列 'test' 的類型為 CHAR(4),然而在較早的版本中,你得到的卻是 BIGINT

NULLIF(expr1,expr2)
如果 expr1 = expr2 為真,傳回 NULL,否則傳回 expr1。 它等同於 CASE WHEN x = y THEN NULL ELSE x END
mysql> SELECT NULLIF(1,1);
        -> NULL
mysql> SELECT NULLIF(1,2);
        -> 1
注意,如果參數不相等,在 MySQL 中,expr1 被求值兩次。

IF(expr1,expr2,expr3)
如果 expr1 為真(expr1 <> 0 以及 expr1 <> NULL),那麼 IF() 傳回 expr2,否則傳回 expr3IF() 傳回一個數位或字串,這取決於它被使用的語境:
mysql> SELECT IF(1>2,2,3);
        -> 3
mysql> SELECT IF(1<2,'yes','no');
        -> 'yes'
mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
        -> 'no'
如果 expr2expr3 明確地為 NULL,那麼函數 IF() 的傳回值類型為非 NULL 列的類型。(這在選擇在 MySQL 4.0.3 中新加入)。 expr1 是作為一個整數值被計算的,這就意味著,如果測試的是一個浮點型或字串值,就必須進行比較操作:
mysql> SELECT IF(0.1,1,0);
        -> 0
mysql> SELECT IF(0.1<>0,1,0);
        -> 1
在上面第一種情況下,IF(0.1) 傳回 0,是因為 0.1 被轉換為一個整數值,傳回 IF(0) 的測試結果。這可能不是你所期望的。在第二種情況下,比較測試原浮點數是否為一個非零值。比較的結果被作為整數使用。 預設的 IF() 傳回值類型 (當結果儲存在臨時表中時,這是非常重要的) 在 MySQL 3.23 中按下列方式確定:
表達式 傳回值
表達式(expr2)或表達式(expr3)傳回值為字串 字串
表達式(expr2)或表達式(expr3)傳回值為浮點型值 浮點型
表達式(expr2)或表達式(expr3)傳回值為整型 整型
如果表達式(expr2)和表達式(expr3)均是字串,同時兩個字串均是忽略字母大小寫的,那麼傳回值也是忽略字母大小寫的(從 MySQL 3.23.51 開始)。

CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END
第一個形式當 value=compare-value 時傳回 result。第二個形式當第一個為真值的 condition 出現時,傳回該條件的結果。如果沒有相符的結果值,那麼 ELSE 後的結果將被傳回。如果沒有 ELSE 部分,那麼 NULL 被傳回:
mysql> SELECT CASE 1 WHEN 1 THEN "one"
           WHEN 2 THEN "two" ELSE "more" END;
       -> "one"
mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
       -> "true"
mysql> SELECT CASE BINARY "B" WHEN "a" THEN 1 WHEN "b" THEN 2 END;
       -> NULL

傳回值的類型 (INTEGERDOUBLESTRING) 與第一個傳回值(第一個 THEN 後的表達式)的類型相同。

6.3.2 字串函數

如果傳回結果的長度超過伺服器參數 max_allowed_packet 的大小,字串值函數將傳回 NULL。查看章節 5.5.2 調節伺服器參數

對於操作字串位置的函數,第一個位置被標記為 1。

ASCII(str)
傳回字串 str 最左邊的那個字元的 ASCII 碼值。如果 str 是一個空字串,那麼傳回值為 0。如果 str 是一個 NULL,傳回值也是 NULL
mysql> SELECT ASCII('2');
        -> 50
mysql> SELECT ASCII(2);
        -> 50
mysql> SELECT ASCII('dx');
        -> 100
也可參看 ORD() 函數。

ORD(str)
如果字串 str 的最左邊的字元是一個多字節的字元,根據多字節字元的成分字元的 ASCII 碼值通過下面的公式計算傳回那個的編碼:((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]。如果最左邊的字元不是一個多字節字元,傳回值與 ASCII() 函數相同:
mysql> SELECT ORD('2');
        -> 50
CONV(N,from_base,to_base)
在不同的數位基數之間轉換數位。將數位 Nfrom_base 轉換到 to_base,並以字串表示形式傳回。如果任何一個參數為 NULL,那麼傳回值也為 NULL。參數 N 被解釋為是一個整數,但是也可以被指定為一個整數或一個字串。最小基為 2,最大基為 36。如果 to_base 是一個負值,N 將被看作為是一個有符號數位。否則,N 被視為是無符號的。CONV 以 64 位精度工作:
mysql> SELECT CONV("a",16,2);
        -> '1010'
mysql> SELECT CONV("6E",18,8);
        -> '172'
mysql> SELECT CONV(-17,10,-18);
        -> '-H'
mysql> SELECT CONV(10+"10"+'10'+0xa,10,10);
        -> '40'
BIN(N)
傳回 N 的字串表示的二進位值形式,在這裡,N 長長的(BIGINT)數位。這個函數等價於 CONV(N,10,2)。如果 N 是一個 NULL,傳回值也是 NULL
mysql> SELECT BIN(12);
        -> '1100'
OCT(N)
傳回 N 的字串表示的八進制值形式,在這裡,N 是一個長長的數位。這個函數等價於 CONV(N,10,8)。如果 N 是一個 NULL,傳回值也是 NULL
mysql> SELECT OCT(12);
        -> '14'
HEX(N_or_S)
如果 N_OR_S 是一個數位,傳回 N 的字串表示的十六進制值形式,這裡 N 是一個長長的(BIGINT)數位。這個函數等價於 CONV(N,10,16)。 如果 N_OR_S 是一個字串,N_OR_S 中的每個字元均被轉換為 2 位十六進制數位,並以十六進制的字串形式傳回。這是 0xff 形式的字串反轉操作。
mysql> SELECT HEX(255);
        -> 'FF'
mysql> SELECT HEX("abc");
        -> 616263
mysql> SELECT 0x616263;
        -> "abc"
CHAR(N,...)
CHAR() 以整數類型解釋參數,傳回這個整數所代表的 ASCII 碼值給出的字元組成的字串。NULL 值將被忽略:
mysql> SELECT CHAR(77,121,83,81,'76');
        -> 'MySQL'
mysql> SELECT CHAR(77,77.3,'77.3');
        -> 'MMM'
CONCAT(str1,str2,...)
將參數連線成字串傳回。如果有任何一個參數為 NULL,傳回值也為 NULL。可以有超過 2 個的參數。數位參數將被轉換為相等價的字串形式:
mysql> SELECT CONCAT('My', 'S', 'QL');
        -> 'MySQL'
mysql> SELECT CONCAT('My', NULL, 'QL');
        -> NULL
mysql> SELECT CONCAT(14.3);
        -> '14.3'
CONCAT_WS(separator, str1, str2,...)
CONCAT_WS() 支援 CONCAT 加上一個分隔符,它是一個特殊形式的 CONCAT()。第一個參數剩餘參數間的分隔符。分隔符可以是與剩餘參數一樣的字串。如果分隔符是 NULL,傳回值也將為 NULL。這個函數會跳過分隔符參數後的任何 NULL 和空字串。分隔符將被加到被連線的字串之間:
mysql> SELECT CONCAT_WS(",","First name","Second name","Last Name");
       -> 'First name,Second name,Last Name'
mysql> SELECT CONCAT_WS(",","First name",NULL,"Last Name");
       -> 'First name,Last Name'
LENGTH(str)
OCTET_LENGTH(str)
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)
傳回字串 str 的長度:
mysql> SELECT LENGTH('text');
        -> 4
mysql> SELECT OCTET_LENGTH('text');
        -> 4
注意,CHAR_LENGTH()CHARACTER_LENGTH() 對於多字節字元只計數一次。

BIT_LENGTH(str)
傳回字串 str 的比特長度:
mysql> SELECT BIT_LENGTH('text');
        -> 32
LOCATE(substr,str)
POSITION(substr IN str)
傳回幾串 substr 在字串 str 中第一次出現的位置。如果幾串 substrstr 中不存在,傳回值為 0
mysql> SELECT LOCATE('bar', 'foobarbar');
        -> 4
mysql> SELECT LOCATE('xbar', 'foobar');
        -> 0
這個函數是多字節安全的。在 MySQL 3.23 中,這個函數是字母大小寫敏感的,當在 MySQL 4.0 中時,如有任一參數是一個二進位字串,它才是字母大小寫敏感的。

LOCATE(substr,str,pos)
傳回幾串 substr 在字串 str 中的第 pos 位置後第一次出現的位置。如果 substr 不在 str 中傳回 0
mysql> SELECT LOCATE('bar', 'foobarbar',5);
        -> 7
這個函數是多字節安全的。在 MySQL 3.23 中,這個函數是字母大小寫敏感的,當在 MySQL 4.0 中時,如有任一參數是一個二進位字串,它才是字母大小寫敏感的。

INSTR(str,substr)
傳回幾串 substr 在字串 str 中第一次出現的位置。這與有兩個參數形式的 LOCATE() 相似,只是參數的位置被顛倒了:
mysql> SELECT INSTR('foobarbar', 'bar');
        -> 4
mysql> SELECT INSTR('xbar', 'foobar');
        -> 0
這個函數是多字節安全的。在 MySQL 3.23 中,這個函數是字母大小寫敏感的,當在 MySQL 4.0 中時,如有任一參數是一個二進位字串,它才是字母大小寫敏感的。

LPAD(str,len,padstr)
用字串 padstrstr 進行左邊填補直至它的長度達到 len 個字元長度,然後傳回 str。如果 str 的長度長於 len',那麼它將被截除到 len 個字元。
mysql> SELECT LPAD('hi',4,'??');
        -> '??hi'
RPAD(str,len,padstr)
用字串 padstrstr 進行右邊填補直至它的長度達到 len 個字元長度,然後傳回 str。如果 str 的長度長於 len',那麼它將被截除到 len 個字元。
mysql> SELECT RPAD('hi',5,'?');
        -> 'hi???'
LEFT(str,len)
傳回字串 str 中最左邊的 len 個字元:
mysql> SELECT LEFT('foobarbar', 5);
        -> 'fooba'
這個函數是多字節安全的。

RIGHT(str,len)
傳回字串 str 中最右邊的 len 個字元:
mysql> SELECT RIGHT('foobarbar', 4);
        -> 'rbar'
這個函數是多字節安全的。

SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
MID(str,pos,len)
從字串 strpos 位置起傳回 len 個字元的幾串。使用 FROM 的變體形式是 ANSI SQL92 的句法:
mysql> SELECT SUBSTRING('Quadratically',5,6);
        -> 'ratica'
這個函數是多字節安全的。

SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
從字串 strpos 位置起傳回幾串:
mysql> SELECT SUBSTRING('Quadratically',5);
        -> 'ratically'
mysql> SELECT SUBSTRING('foobarbar' FROM 4);
        -> 'barbar'
這個函數是多字節安全的。

SUBSTRING_INDEX(str,delim,count)
傳回字串 str 中在第 count 個出現的分隔符 delim 之前的幾串。如果 count 是一個正數,傳回從最後的(從左邊開始計數)分隔符到左邊所有字元。如果 count 是負數,傳回從最後的(從右邊開始計數)分隔符到右邊所有字元:
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
        -> 'www.mysql'
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
        -> 'mysql.com'
這個函數是多字節安全的。

LTRIM(str)
傳回移除了領頭的空格字元後的 str
mysql> SELECT LTRIM('  barbar');
        -> 'barbar'

RTRIM(str)
傳回移除了尾部的空格字元後的 str
mysql> SELECT RTRIM('barbar   ');
        -> 'barbar'
這個函數是多字節安全的。

TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
移除字串 str 中所有的 remstr 前綴或後綴,然後將其傳回。如果沒有任何 BOTHLEADINGTRAILING 修飾符被給出,BOTH 被假定。如果 remstr 沒有被指定,空格將被移除:
mysql> SELECT TRIM('  bar   ');
        -> 'bar'
mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
        -> 'barxxx'
mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
        -> 'bar'
mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
        -> 'barx'
這個函數是多字節安全的。

SOUNDEX(str)
傳回 str 的近音字。兩個發音差不多的字串應該有同樣的近音字。一個標準的近音字為 4 個字元長,但是函數 SOUNDEX() 卻傳回一個任意長的字串。你可以在結果上使用 SUBSTRING() 標準的近音字。提供的字元中所有的非數位字母的字元均被忽略。所有在 A-Z 範圍之外的國際 alpha 字元被視為元音:
mysql> SELECT SOUNDEX('Hello');
        -> 'H400'
mysql> SELECT SOUNDEX('Quadratically');
        -> 'Q36324'

SPACE(N)
傳回有 N 空格字元組成的字串:
mysql> SELECT SPACE(6);
        -> '      '

REPLACE(str,from_str,to_str)
在字串 str 中所有出現的字串 from_str 均被 to_str取代,然後傳回這個字串:
mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
        -> 'WwWwWw.mysql.com'
這個函數是多字節安全的。

REPEAT(str,count)
傳回一個由重復了 count 次的字串 str 組成的字串。如果 count <= 0,傳回一個空字串。如果 strcountNULL,傳回值也為 NULL
mysql> SELECT REPEAT('MySQL', 3);
        -> 'MySQLMySQLMySQL'

REVERSE(str)
以顛倒的字元順序傳回字串 str
mysql> SELECT REVERSE('abc');
        -> 'cba'
這個函數是多字節安全的。

INSERT(str,pos,len,newstr)
在字串 str 中,將從 pos 位置開始,len 個字元長的幾串取代為字串 newstr ,然後將結果傳回:
mysql> SELECT INSERT('Quadratic', 3, 4, 'What');
        -> 'QuWhattic'
這個函數是多字節安全的。

ELT(N,str1,str2,str3,...)
如果 N = 1,傳回 str1,如果N = 2,傳回 str2,等等。如果 N 小於 1 或大於參數的數量,傳回 NULLELT() FIELD() 反運算:
mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
        -> 'ej'
mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
        -> 'foo'

FIELD(str,str1,str2,str3,...)
傳回 str 在清單 str1, str2, str3, ... 中的索引。如果 str 沒有發現,傳回 0FIELD()ELT() 的反運算:
mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 2
mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 0

FIND_IN_SET(str,strlist)
Returns a value 如果字串 str 在由 N 個幾串組成的清單 strlist 中,傳回一個 1N 的值。一個字串清單是由通過字元 “,” 分隔的多個幾串組成。如果第一個參數是一個常數位元串,並且第二個參數是一個 SET 列類型,FIND_IN_SET() 函數將被最佳化為使用位運算!如果 str 在不 strlist 中或者如果 strlist 是一個空串,傳回值為 0。如果任何一個參數為 NULL,傳回值也是 NULL。如果第一個參數包含一個 “,”,這個函數將完全不能工作:
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
        -> 2

MAKE_SET(bits,str1,str2,...)
傳回一個集合 (包含由字元 “,” 分隔的多個幾串組成的一個字串),它由在 bits 集合中有相應的比特位的字串組成。str1 對應於比特位 0,str2 對應比特位 1,等等。在 str1, str2, ... 中的 NULL 串不允許被加入到結果中:
mysql> SELECT MAKE_SET(1,'a','b','c');
        -> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
        -> 'hello,world'
mysql> SELECT MAKE_SET(0,'a','b','c');
        -> ''

EXPORT_SET(bits,on,off,[separator,[number_of_bits]])
傳回一個字串,對於在 'bits' 中的每個比特字位,你將得到一個 'on' 字元,而如果比特字位是一個清零比特位(reset bit)你將得到一個 'off' 字串。每個字串均被“分隔符”(預設為“,”)分隔,並且只有 'number_of_bits'(預設為 64) 個 'bits' 被使用:
mysql> SELECT EXPORT_SET(5,'Y','N',',',4)
        -> Y,N,Y,N
範例(譯者注):
mysql> select EXPORT_SET(1,'1','0','',5);
        -> 10000 
# 最左邊第一位為 2 的 0 次冪

mysql> select EXPORT_SET(2,'1','0','',5);
        -> 01000
# 最左邊第一位為 2 的 0 次冪,第二位為 2 的 1 次冪        

mysql> select EXPORT_SET(4,'1','0','',5);
        -> 00100
# 最左邊第一位為 2 的 0 次冪,第二位為 2 的 1 次冪,第三位為 2 的 2 次冪  

mysql> select EXPORT_SET(15,'1','0','',5);
        -> 11110
# 最左邊第一位為 2 的 1 次冪,第四位為 2 的 3 次冪  

mysql> select EXPORT_SET(16,'1','0','',5);
        -> 00001
# 最左邊第一位為 2 的 1 次冪,第五位為 2 的 4 次冪 


# 以上結果在 MySQL 4.0.12 中測試通過
範例結束(譯者注)

LCASE(str)
LOWER(str)
依照目前字元集設定映射(預設為 ISO-8859-1 Latin1),將字串 str 中的所有字元改變為小寫,然後傳回該值:
mysql> SELECT LCASE('QUADRATICALLY');
        -> 'quadratically'
這個函數是多字節安全的。

UCASE(str)
UPPER(str)
依照目前字元集設定映射(預設為 ISO-8859-1 Latin1),將字串 str 中的所有字元改變為大寫,然後傳回該值:
mysql> SELECT UCASE('Hej');
        -> 'HEJ'
這個函數是多字節安全的。

LOAD_FILE(file_name)
讀入文件,並將文件內容作為一個字串傳回。這個文件必須在伺服器上,必須指定文件完整的路徑名,並且你必須有 FILE 權限。文件必須完全可讀,並且小於 max_allowed_packet。 如果該文件不存在,或因為上面的任一原因而不能被讀出,函數傳回 NULL
mysql> UPDATE tbl_name
           SET blob_column=LOAD_FILE("/tmp/picture")
           WHERE id=1;
如果你沒有使用 MySQL 3.23,你不得不在你的應用程式中讀取文件,以文件的資訊建立一個 INSERT 語句,來更新資料庫。如果你使用 MySQL++ 庫,下面有一個範例,詳細請查看 http://www.mysql.com/documentation/mysql++/mysql++-examples.html

QUOTE(str)
參照一個字串,並傳回一個結果,該結果可作為一個適當轉義過的資料值在一個 SQL 語句中使用。字串被單引號包圍著傳回,並且在該字串中每個單引號(“'”)、反斜線符號(“\”)、ASCII NUL 和 Control-Z 出現的地方,在該字元之前均被加上了一個反斜線。如果參數是 NULL,那麼結果值是一個沒有單引號包圍的單詞 “NULL”。 QUOTE 函數在 MySQL 4.0.3 中被加入。
mysql> SELECT QUOTE("Don't");
        -> 'Don\'t!'
mysql> SELECT QUOTE(NULL);
        -> NULL

6.3.2.1 字串比較函數

在必要的時候,MySQL 會自動地將數位轉換到字串,反之亦然:

mysql> SELECT 1+"1";
        -> 2
mysql> SELECT CONCAT(2,' test');
        -> '2 test'

如果你希望明確地將一個數位轉換為字串,將它參數傳遞到 CONCAT() 中。

如果將一個二進位字串作為參數傳遞給一個字串函數,結果傳回也是一個二進位字串。一個數位被轉換到字串,該字串被視為是一個二進位字串。這僅僅會影響結果。

通常,只要字串比較中的任何一個表達式是區分大小寫的,比較就會以字母大小寫敏感方式執行。

expr LIKE pat [ESCAPE 'escape-char']
使用 SQL 的簡單的正規表達式進行比較的樣式相符。傳回 1 (TRUE) 或 0 (FALSE)。可以在樣式中使用下面所示的兩個通配符字元與 LIKE 配合:
字元 含義
% 相符任意多個字元,甚至是零個字元
_ 嚴格地相符一個字元
mysql> SELECT 'David!' LIKE 'David_';
        -> 1
mysql> SELECT 'David!' LIKE '%D%v%';
        -> 1
為了測試一個含有通配符的文字案例,可以用轉義符加在能配符前。如果沒有明確指定 ESCAPE 字元,假定為 “\”
字串 含義
\% 相符一個 % 字元
\_ 相符一個 _ 字元
mysql> SELECT 'David!' LIKE 'David\_';
        -> 0
mysql> SELECT 'David_' LIKE 'David\_';
        -> 1
為了指定一個不同的轉義字元,可以使用 ESCAPE 幾句:
mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
        -> 1
下面兩個語句表明,字串比較是忽略大小寫的,除非任一操作數是一個二進位字串:
mysql> SELECT 'abc' LIKE 'ABC';
        -> 1
mysql> SELECT 'abc' LIKE BINARY 'ABC';
        -> 0
LIKE 允許用在一個數位表達式上。(這是 MySQL 對 ANSI SQL LIKE 的擴展。)
mysql> SELECT 10 LIKE '1%';
        -> 1
注意:因為 MySQL 在字串中使用的是 C 的轉義句法(例如 “\n”),所以在 LIKE 字串中使用的任何一個 “\” 必須被雙寫。例如,為了尋找 “\n”,必須以 “\\n” 形式指定它。為了尋找 “\”,必須指定它為 “\\\\” (反斜線被語法分析器剝離一次,另一次在樣式相符時完成,留下一條單獨的反斜線被相符)。

expr NOT LIKE pat [ESCAPE 'escape-char']
相同於 NOT (expr LIKE pat [ESCAPE 'escape-char'])

expr SOUNDS LIKE expr
等同於 SOUNDEX(expr)=SOUNDEX(expr) (適用於 MySQL 4.1 或更新的版本)。

expr REGEXP pat
expr RLIKE pat
依照樣式 pat 對字串表達式 expr 執行一個樣式比較。樣式可以是一個擴展的正則表達式。查看章節 G MySQL 正則表達式。Returns 如果表達式 expr 相符 pat,傳回 1,否則傳回 0RLIKEREGEXP 的同義詞,它提供了與 mSQL 的兼容。注意:MySQL 在字串中使用的是 C 的轉義句法(例如 “\n”),所以在 REGEXP 字串中使用的任何一個 “\” 必須被雙寫。在 MySQL 3.23.4 中,REGEXP 對於正常的(不是二進位)字串是忽略大小寫的:
mysql> SELECT 'Monty!' REGEXP 'm%y%%';
        -> 0
mysql> SELECT 'Monty!' REGEXP '.*';
        -> 1
mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
        -> 1
mysql> SELECT "a" REGEXP "A", "a" REGEXP BINARY "A";
        -> 1  0
mysql> SELECT "a" REGEXP "^[a-d]";
        -> 1
當決定一個字元的類型時,REGEXPRLIKE 使用目前使用的字元集(預設為 ISO-8859-1 Latin1)。

expr NOT REGEXP pat
expr NOT RLIKE pat
等同於 NOT (expr REGEXP pat)

STRCMP(expr1,expr2)
如果字串是相同,STRCMP() 傳回 0,如果第一個參數根據目前排序次序小於第二個參數,傳回 -1,否則傳回 1
mysql> SELECT STRCMP('text', 'text2');
        -> -1
mysql> SELECT STRCMP('text2', 'text');
        -> 1
mysql> SELECT STRCMP('text', 'text');
        -> 0

MATCH (col1,col2,...) AGAINST (expr)
MATCH (col1,col2,...) AGAINST (expr IN BOOLEAN MODE)
MATCH ... AGAINST() 用於全文搜尋,傳回在列 (col1,col2,...) 和查詢 expr 之間純文字的相關相似的尺度。相關性是一個正的浮點型數位。零相關性意味著不相似。MATCH ... AGAINST() 可用於 MySQL 3.23.23 或更新的版本中。IN BOOLEAN MODE 擴展在 MySQL 4.0.1 中被新加入。詳細描述和使用範例,請查看 6.8 MySQL 全文搜尋

6.3.2.2 字母大小寫敏感性

BINARY
BINARY 運算子將跟在它後面的字串強制作為一個二進位字串。這可以很容易地強制一個列的比較以字母大小寫敏感方式進行,即使該列沒有定義為 BINARYBLOB?
mysql> SELECT "a" = "A";
        -> 1
mysql> SELECT BINARY "a" = "A";
        -> 0
BINARY stringCAST(string AS BINARY) 的縮寫。查看章節 6.3.5 Cast 函數BINARY 在 MySQL 3.23.0 中被加入。 注意,當將一個索引列強制為 BINARY 時,在某些語境中,MySQL 將不能有效地使用索引。

如果希望對一個 blob 進行忽略字母大小的比較時,你通常可以在比較前將它轉換到大寫:

SELECT 'A' LIKE UPPER(blob_col) FROM table_name;

我們計劃不久推出在不同字元集間的轉化,以使字串比較有更好的伸縮性。

6.3.3 數位函數

6.3.3.1 算術運算

常用的算術運算子均是可用的。注意,如果兩個參數均是整型,`-', `+'`*'BIGINT (64 位)精度運算並傳回結果!如果一個參數是一個無符號的整數,另一個參數也是一個整數,結果也將是一個無符號整數。查看章節 6.3.5 Cast 函數

+
加法:
mysql> SELECT 3+5;
        -> 8
-
減法:
mysql> SELECT 3-5;
        -> -2
*
乘法:
mysql> SELECT 3*5;
        -> 15
mysql> SELECT 18014398509481984*18014398509481984.0;
        -> 324518553658426726783156020576256.0
mysql> SELECT 18014398509481984*18014398509481984;
        -> 0
最後一個表達式的結果是錯誤的,這是因為乘法結果超過了 64 位 BIGINT 計算範圍。
/
除法:
mysql> SELECT 3/5;
        -> 0.60
被 0 除將傳回一個 NULL 結果:
mysql> SELECT 102/(1-1);
        -> NULL
只有當在一個結果被轉換到一個整數的語境中執行時,除法將會以 BIGINT 進行算術計算。

6.3.3.2 數學函數

所有的數學函數在發生錯誤的情況下,均傳回 NULL

-
一元減。 改變參數的符號:
mysql> SELECT - 2;
        -> -2
注意,如果這個運算子被用於一個 BIGINT,傳回值也是一個 BIGINT!這就意味著,應該避免在一個可能有值 -2^63 的整數上使用 - 運算子!

ABS(X)
傳回 X 的絕對值:
mysql> SELECT ABS(2);
        -> 2
mysql> SELECT ABS(-32);
        -> 32
這個函數可安全地使用於 BIGINT 值。

SIGN(X)
-101 方式傳回參數的符號,它取決於參數 X 是負數、0 或正數。
mysql> SELECT SIGN(-32);
        -> -1
mysql> SELECT SIGN(0);
        -> 0
mysql> SELECT SIGN(234);
        -> 1
MOD(N,M)
%
取模 (就如 C 中的 % 運算子)。傳回 NM 除後的餘數:
mysql> SELECT MOD(234, 10);
        -> 4
mysql> SELECT 253 % 7;
        -> 1
mysql> SELECT MOD(29,9);
        -> 2
mysql> SELECT 29 MOD 9;
        -> 2
這個函數可安全地使用於 BIGINT 值。最後一個範例可在 MySQL 4.1 中工作。

FLOOR(X)
傳回不大於 X 的最大整數值:
mysql> SELECT FLOOR(1.23);
        -> 1
mysql> SELECT FLOOR(-1.23);
        -> -2
注意,傳回值被轉換為一個 BIGINT

CEILING(X)
傳回不小於 X 的最小整數:
mysql> SELECT CEILING(1.23);
        -> 2
mysql> SELECT CEILING(-1.23);
        -> -1
注意,傳回值被轉換為一個 BIGINT

ROUND(X)
ROUND(X,D)
將參數 X 四舍五入到最近的整數,然後傳回。 兩個參數的形式是將一個數位四舍五入到 D 個小數後傳回。
mysql> SELECT ROUND(-1.23);
        -> -1
mysql> SELECT ROUND(-1.58);
        -> -2
mysql> SELECT ROUND(1.58);
        -> 2
mysql> SELECT ROUND(1.298, 1);
        -> 1.3
mysql> SELECT ROUND(1.298, 0);
        -> 1
注意,當參數在兩個整數之間時, ROUND() 的行為取決於 C 庫的實現。某些取整到最近的偶數,總是向下取,總是向上取,也可能總是接近於零。如果你需要某種取整類型,應該使用一個明確定義的函數比如 TRUNCATE()FLOOR() 代替。

DIV
整除。 類似於 FLOOR(),但是它可安全地用於 BIGINT 值。
mysql> SELECT 5 DIV 2
	-> 2
DIV 在 MySQL 4.1.0 中新加入。

EXP(X)
傳回值 e (自然對數的底) 的 X 次方:
mysql> SELECT EXP(2);
        -> 7.389056
mysql> SELECT EXP(-2);
        -> 0.135335
LN(X)
傳回 X 的自然對數:
mysql> SELECT LN(2);
        -> 0.693147
mysql> SELECT LN(-2);
        -> NULL
這個函數在 MySQL 4.0.3 被新加入。 在 MySQL 中,它是 LOG(X) 的同義詞。

LOG(X)
LOG(B,X)
如果以一個參數調用,它傳回 X 的自然對數:
mysql> SELECT LOG(2);
        -> 0.693147
mysql> SELECT LOG(-2);
        -> NULL
如果以兩個參數調用,這個函數傳回 X 任意底 B 的對數:
mysql> SELECT LOG(2,65536);
        -> 16.000000
mysql> SELECT LOG(1,100);
        -> NULL
任意底選項在 MySQL 4.0.3 中被加入。LOG(B,X) 等價於 LOG(X)/LOG(B)

LOG2(X)
傳回 X 的以 2 為底的對數:
mysql> SELECT LOG2(65536);
        -> 16.000000
mysql> SELECT LOG2(-100);
        -> NULL
LOG2() 通常可以用於計數出一個數位需要多少個比特位用於儲存它。這個函數在 MySQL 4.0.3 中被加入。在更早的版本中,可以使用 LOG(X)/LOG(2) 來代替它。

LOG10(X)
傳回 X 以 10 為底的對數:
mysql> SELECT LOG10(2);
        -> 0.301030
mysql> SELECT LOG10(100);
        -> 2.000000
mysql> SELECT LOG10(-100);
        -> NULL
POW(X,Y)
POWER(X,Y)
傳回 XY 冪:
mysql> SELECT POW(2,2);
        -> 4.000000
mysql> SELECT POW(2,-2);
        -> 0.250000
SQRT(X)
傳回 X 的非否平方根:
mysql> SELECT SQRT(4);
        -> 2.000000
mysql> SELECT SQRT(20);
        -> 4.472136
PI()
傳回 PI 值(圓周率)。缺少顯示 5 位小數,但是在 MySQL 內部,為 PI 使用全部的雙精度。
mysql> SELECT PI();
        -> 3.141593
mysql> SELECT PI()+0.000000000000000000;
        -> 3.141592653589793116
COS(X)
傳回 X 的餘弦,在這裡,X 以弧度給出:
mysql> SELECT COS(PI());
        -> -1.000000
SIN(X)
傳回 X 的正弦,在這裡,X 以弧度給出:
mysql> SELECT SIN(PI());
        -> 0.000000
TAN(X)
傳回 X 的正切,在這裡,X 以弧度給出:
mysql> SELECT TAN(PI()+1);
        -> 1.557408
ACOS(X)
傳回 X 的反餘弦,更確切地說,傳回餘弦值為 X 的值。如果 X 不在 -11 之間的範圍內,傳回 NULL
mysql> SELECT ACOS(1);
        -> 0.000000
mysql> SELECT ACOS(1.0001);
        -> NULL
mysql> SELECT ACOS(0);
        -> 1.570796
ASIN(X)
傳回 X 的反正弦,更確切地說,傳回正弦值為 X 的值。如果 X 不在 -11 之間的範圍內,傳回 NULL
mysql> SELECT ASIN(0.2);
        -> 0.201358
mysql> SELECT ASIN('foo');
        -> 0.000000
ATAN(X)
傳回 X 的反正切, 更確切地說,傳回正切值為 X 的值:
mysql> SELECT ATAN(2);
        -> 1.107149
mysql> SELECT ATAN(-2);
        -> -1.107149
ATAN(Y,X)
ATAN2(Y,X)
傳回兩個變數 XY 的反正切。它類似於計算 Y / X 的反正切,除了兩個參數的符號用於決定結果的象限:
mysql> SELECT ATAN(-2,2);
        -> -0.785398
mysql> SELECT ATAN2(PI(),0);
        -> 1.570796
COT(X)
傳回 X 的餘切:
mysql> SELECT COT(12);
        -> -1.57267341
mysql> SELECT COT(0);
        -> NULL
RAND()
RAND(N)
傳回一個範圍在 01.0 之間的隨機浮點值。 如果一個整數參數 N 被指定,它被當做種幾值使用(用於產生一個可重復的數值):
mysql> SELECT RAND();
        -> 0.9233482386203
mysql> SELECT RAND(20);
        -> 0.15888261251047
mysql> SELECT RAND(20);
        -> 0.15888261251047
mysql> SELECT RAND();
        -> 0.63553050033332
mysql> SELECT RAND();
        -> 0.70100469486881
在一個 ORDER BY 幾句中,不可以使用 RAND() 值使用一個列,因為 ORDER BY 將多次重復計算列。從 MySQL 3.23 開始,你可以使用:SELECT * FROM table_name ORDER BY RAND(),這有利於得到一個來自 SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000 的集合中的隨機樣本。 注意,在一個 WHERE 幾句中的 RAND() 將在每次 WHERE 執行時被重新計算。 RAND() 並不是預期完美的隨機數發生器,但是可以代替做為產生特別的隨機數一個快速的方法,這樣便於在兩個不同平台下的同一 MySQL 版本間移動。

LEAST(X,Y,...)
有兩個或更多個參數,傳回最小(最小值)的參數。參數使用下列規則進行比較:
mysql> SELECT LEAST(2,0);
        -> 0
mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
        -> 3.0
mysql> SELECT LEAST("B","A","C");
        -> "A"
在早於 MySQL 3.22.5 的版本中,你可以使用 MIN() 代替 LEAST

GREATEST(X,Y,...)
傳回最大(最大值)參數。 參數使用與 LEAST 一致的規則進行比較:
mysql> SELECT GREATEST(2,0);
        -> 2
mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
        -> 767.0
mysql> SELECT GREATEST("B","A","C");
        -> "C"
在早於 MySQL 3.22.5 的版本中,可以使用 MAX() 代替 GREATEST

DEGREES(X)
將參數 X 從弧度轉換為角度,然後傳回:
mysql> SELECT DEGREES(PI());
        -> 180.000000
RADIANS(X)
將參數 X 從角度轉換為弧度,然後傳回:
mysql> SELECT RADIANS(90);
        -> 1.570796
TRUNCATE(X,D)
將數值 X 截到 D 個小數,然後傳回。如果 D0,結果將不包含小數點和小數部分:
mysql> SELECT TRUNCATE(1.223,1);
        -> 1.2
mysql> SELECT TRUNCATE(1.999,1);
        -> 1.9
mysql> SELECT TRUNCATE(1.999,0);
        -> 1
mysql> SELECT TRUNCATE(-1.999,1);
        -> -1.9
從 MySQL 3.23.51 開始,所有數位被四舍五入到零。 如果 D 是負數,那麼數位的整個部分被對準零位輸出:
mysql> SELECT TRUNCATE(122,-2);
       -> 100
注意, 十進值小數在計算機中通常不以精確數位儲存,而是雙精度型的值,你可能會被下列結果所愚弄:
mysql> SELECT TRUNCATE(10.28*100,0);
       -> 1027
上面結果的發生是因為 10.28 實際上是以某些像 10.2799999999999999 的形式被儲存的。

6.3.4 日期和時間函數

對於每個類型的值範圍以及日期和時間值有效指定格式,請查看章節 6.2.2 Date 和 Time 類型

這裡是一個使用日期函數的範例。下面的查詢選擇所有 date_col 值在最後 30 天內的記錄。

mysql> SELECT something FROM tbl_name
           WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date)
傳回 date 的星期索引(1 = Sunday, 2 = Monday, ... 7 = Saturday)。索引值符合 ODBC 的標準。
mysql> SELECT DAYOFWEEK('1998-02-03');
        -> 3
WEEKDAY(date)
傳回 date 的星期索引(0 = Monday, 1 = Tuesday, ... 6 = Sunday):
mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
        -> 1
mysql> SELECT WEEKDAY('1997-11-05');
        -> 2
DAYOFMONTH(date)
傳回 date 是一月中的第幾天,範圍為 131
mysql> SELECT DAYOFMONTH('1998-02-03');
        -> 3
DAYOFYEAR(date)
傳回 date 是一年中的第幾天,範圍為 1366
mysql> SELECT DAYOFYEAR('1998-02-03');
        -> 34
MONTH(date)
傳回 date 中的月份,範圍為 112
mysql> SELECT MONTH('1998-02-03');
        -> 2
DAYNAME(date)
傳回 date 的星期名:
mysql> SELECT DAYNAME("1998-02-05");
        -> 'Thursday'
MONTHNAME(date)
傳回 date 的月份名:
mysql> SELECT MONTHNAME("1998-02-05");
        -> 'February'
QUARTER(date)
傳回 date 在一年中的季度,範圍為 14
mysql> SELECT QUARTER('98-04-01');
        -> 2
WEEK(date)
WEEK(date,first)
對於星期日是一周中的第一天的場合,如果函數只有一個參數調用,傳回 date 為一年的第幾周,傳回值範圍為 053 (是的,可能有第 53 周的開始)。兩個參數形式的 WEEK() 允許你指定一周是否以星期日或星期一開始,以及傳回值為 0-53 還是 1-52。 這裡的一個表顯示第二個參數是如何工作的:
含義
0 一周以星期日開始,傳回值範圍為 0-53
1 一周以星期一開始,傳回值範圍為 0-53
2 一周以星期日開始,傳回值範圍為 1-53
3 一周以星期一開始,傳回值範圍為 1-53 (ISO 8601)
mysql> SELECT WEEK('1998-02-20');
        -> 7
mysql> SELECT WEEK('1998-02-20',0);
        -> 7
mysql> SELECT WEEK('1998-02-20',1);
        -> 8
mysql> SELECT WEEK('1998-12-31',1);
        -> 53
注意,在版本 4.0 中,WEEK(#,0) 被變更為相符 USA 歷法。 注意,如果一周是上一年的最後一周,當你沒有使用 2 或 3 做為可選參數時,MySQL 將傳回 0:
mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
        -> 2000, 0
mysql> SELECT WEEK('2000-01-01',2);
        -> 52
你可能會爭辯說,當給定的日期值實際上是 1999 年的第 52 周的一部分時,MySQL 對 WEEK() 函數應該傳回 52。我們決定傳回 0 ,是因為我們希望該函數傳回“在指定年份中是第幾周”。 當與其它的提取日期值中的月日值的函數結合使用時,這使得 WEEK() 函數的用法可靠。 如果你更希望能得到恰當的年-周值,那麼你應該使用參數 2 或 3 做為可選參數,或者使用函數 YEARWEEK()
mysql> SELECT YEARWEEK('2000-01-01');
        -> 199952
mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2);
        -> 52
YEAR(date)
傳回 date 的年份,範圍為 10009999
mysql> SELECT YEAR('98-02-03');
        -> 1998
YEARWEEK(date)
YEARWEEK(date,first)
傳回一個日期值是的哪一年的哪一周。第二個參數的形式與作用完全與 WEEK() 的第二個參數一致。注意,對於給定的日期參數是一年的第一周或最後一周的,傳回的年份值可能與日期參數給出的年份不一致:
mysql> SELECT YEARWEEK('1987-01-01');
        -> 198653
注意,對於可選參數 0 或 1,周值的傳回值不同於 WEEK() 函數所傳回值(0), WEEK() 根據給定的年語境傳回周值。
HOUR(time)
傳回 time 的小時值,範圍為 023
mysql> SELECT HOUR('10:05:03');
        -> 10
MINUTE(time)
傳回 time 的分鐘值,範圍為 059
mysql> SELECT MINUTE('98-02-03 10:05:03');
        -> 5
SECOND(time)
傳回 time 的秒值,範圍為 059
mysql> SELECT SECOND('10:05:03');
        -> 3
PERIOD_ADD(P,N)
增加 N 個月到時期 P(格式為 YYMMYYYYMM)中。以 YYYYMM 格式傳回值。 注意,期間參數 P 不是 一個日期值:
mysql> SELECT PERIOD_ADD(9801,2);
        -> 199803
PERIOD_DIFF(P1,P2)
傳回時期 P1P2 之間的月數。P1P2 應該以 YYMMYYYYMM 指定。 注意,時期參數 P1P2 不是 日期值:
mysql> SELECT PERIOD_DIFF(9802,199703);
        -> 11
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)
這些函數執行日期的算術運算。ADDDATE()SUBDATE() 分別是 DATE_ADD()DATE_SUB() 的同義詞。 在 MySQL 3.23 中,如果表達式的右邊是一個日期值或一個日期時間型欄位,你可以使用 +- 代替 DATE_ADD()DATE_SUB()(範例如下)。 參數 date 是一個 DATETIMEDATE 值,指定一個日期的開始。expr 是一個表達式,指定從開始日期上增加還是減去間隔值。expr 是一個字串﹔它可以以一個 “-” 領頭表示一個負的間隔值。type 是一個關鍵詞,它標志著表達式以何格式被解釋。 下表顯示 typeexpr 參數是如何關聯的:
type expr 期望的格式
SECOND SECONDS
MINUTE MINUTES
HOUR HOURS
DAY DAYS
MONTH MONTHS
YEAR YEARS
MINUTE_SECOND "MINUTES:SECONDS"
HOUR_MINUTE "HOURS:MINUTES"
DAY_HOUR "DAYS HOURS"
YEAR_MONTH "YEARS-MONTHS"
HOUR_SECOND "HOURS:MINUTES:SECONDS"
DAY_MINUTE "DAYS HOURS:MINUTES"
DAY_SECOND "DAYS HOURS:MINUTES:SECONDS"
expr 的格式中,MySQL 允許任何字元作為定界符。表中所顯示的是建議的定界字元。如果 date 參數是一個 DATE 值,並且計算的間隔僅僅有 YEARMONTHDAY 部分(沒有時間部分),那麼傳回值也是一個 DATE 值。否則傳回值是一個 DATETIME 值:
mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
        -> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
        -> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
       -> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
    ->                 INTERVAL 1 SECOND);
        -> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
    ->                 INTERVAL 1 DAY);
        -> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
    ->                 INTERVAL "1:1" MINUTE_SECOND);
        -> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
    ->                 INTERVAL "1 1:1:1" DAY_SECOND);
        -> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
    ->                 INTERVAL "-1 10" DAY_HOUR);
        -> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
        -> 1997-12-02
如果你指定了一個太短的間隔值(沒有包括 type 關鍵詞所期望的所有間隔部分),MySQL 假設你遺漏了間隔值的最左邊部分。例如,如果指定一個 typeDAY_SECOND,那麼 expr 值被期望包含天、小時、分鐘和秒部分。如果你象 "1:10" 樣指定一個值,MySQL 假設天和小時部分被遺漏了,指定的值代表分鐘和秒。換句話說,"1:10" DAY_SECOND 被解釋為等價於 "1:10" MINUTE_SECOND。這類似於 MySQL 解釋 TIME 值為經過的時間而不是一天的時刻。 注意,如果依著包含一個時間部分的間隔增加或減少一個日期值,該日期值將被自動地轉換到一個日期時間值:
mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 DAY);
       -> 1999-01-02
mysql> SELECT DATE_ADD("1999-01-01", INTERVAL 1 HOUR);
       -> 1999-01-01 01:00:00
如果你使用了確定不正確的日期,傳回結果將是 NULL。如果你增加 MONTHYEAR_MONTHYEAR,並且結果日期的天比新月份的最大天數還大,那麼它將被調整到新月份的最大天數:
mysql> SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH);
        -> 1998-02-28
注意,上面的範例中,單詞 INTERVAL 和關鍵詞 type 是不區分字母大小寫的。

EXTRACT(type FROM date)
EXTRACT() 函數使用與 DATE_ADD()DATE_SUB() 一致的間隔類型,但是它用於指定從日期中提取的部分,而不是進行日期算術運算。
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
       -> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
       -> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
       -> 20102
TO_DAYS(date)
給出一個日期 date,傳回一個天數(從 0 年開始的天數):
mysql> SELECT TO_DAYS(950501);
        -> 728779
mysql> SELECT TO_DAYS('1997-10-07');
        -> 729669
TO_DAYS() 無意於使用先於格裡高裡歷法(即現行的陽歷)(1582)出現的值,因為它不考慮當歷法改變時所遺失的天數。

FROM_DAYS(N)
給出一個天數 N,傳回一個 DATE 值:
mysql> SELECT FROM_DAYS(729669);
        -> '1997-10-07'
FROM_DAYS() 無意於使用先於格裡高裡歷法(1582)出現的值,因為它不考慮當歷法改變時所遺失的天數。

DATE_FORMAT(date,format)
依照 format 字串格式化 date 值。下面的修飾符可被用於 format 字串中:
修飾符 含義
%M 月的名字 (January..December)
%W 星期的名字 (Sunday..Saturday)
%D 有英文後綴的某月的第幾天 (0th, 1st, 2nd, 3rd, etc.)
%Y 年份,數位的,4 位
%y 年份,數位的,2 位
%X 周值的年份,星期日是一個星期的第一天,數位的,4 位,與 '%V' 一同使用
%x 周值的年份,星期一是一個星期的第一天,數位的,4 位,與 '%v' 一同使用
%a 縮寫的星期名 (Sun..Sat)
%d 月份中的天數,數位的 (00..31)
%e 月份中的天數,數位的 (0..31)
%m 月,數位的 (00..12)
%c 月,數位的 (0..12)
%b 縮寫的月份名 (Jan..Dec)
%j 一年中的天數 (001..366)
%H 小時 (00..23)
%k 小時 (0..23)
%h 小時 (01..12)
%I 小時 (01..12)
%l 小時 (1..12)
%i 分鐘,數位的 (00..59)
%r 時間,12 小時 (hh:mm:ss [AP]M)
%T 時間,24 小時 (hh:mm:ss)
%S 秒 (00..59)
%s 秒 (00..59)
%p AMPM
%w 一周中的天數 (0=Sunday..6=Saturday)
%U 星期 (00..53),星期日是一個星期的第一天
%u 星期 (00..53),星期一是一個星期的第一天
%V 星期 (01..53),星期日是一個星期的第一天。與 '%X' 一起使用
%v 星期 (01..53),星期一是一個星期的第一天。與 '%x' 一起使用
%% 一個字母 “%”
所有其它的字元不經過解釋,直接復制到結果中:
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
        -> 'Saturday October 1997'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
        -> '22:23:00'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                          '%D %y %a %d %m %b %j');
        -> '4th 97 Sat 04 10 Oct 277'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                          '%H %k %I %r %T %S %w');
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
        -> '1998 52'
在 MySQL 3.23 中,在格式修飾符前需要字元 `%'。在更早的 MySQL 版本中,`%' 是可選的。 月份與天修飾符的範圍從零開始的原因是,在 MySQL 3.23 中,它允許儲存不完善的日期值(例如 '2004-00-00')。

TIME_FORMAT(time,format)
它的使用方法與上面的 DATE_FORMAT() 函數相似,但是 format 字串只包含處理小時、分和秒的那些格式修飾符。使用其它的修飾符會產生一個 NULL 值或 0

CURDATE()
CURRENT_DATE
'YYYY-MM-DD'YYYYMMDD 格式傳回目前的日期值,傳回的格式取決於該函數是用於字串還是數位語境中:
mysql> SELECT CURDATE();
        -> '1997-12-15'
mysql> SELECT CURDATE() + 0;
        -> 19971215
CURTIME()
CURRENT_TIME
'HH:MM:SS'HHMMSS 格式傳回目前的時間值,傳回的格式取決於該函數是用於字串還是數位語境中:
mysql> SELECT CURTIME();
        -> '23:50:26'
mysql> SELECT CURTIME() + 0;
        -> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
'YYYY-MM-DD HH:MM:SS'YYYYMMDDHHMMSS 格式傳回目前的日期時間值,傳回的格式取決於該函數是用於字串還是數位語境中:
mysql> SELECT NOW();
        -> '1997-12-15 23:50:26'
mysql> SELECT NOW() + 0;
        -> 19971215235026
注意,函數 NOW() 在每個查詢中只計算一次,也就是在查詢開始執行時。這就是說,如果在一個單獨的查詢中多次參照了 NOW(),它只會給出值都是一個相同的時間。

UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
如果調用時沒有參數,以無符號的整數形式傳回一個 Unix 時間戳(從 '1970-01-01 00:00:00' GMT 開始的秒數)。如果以一個參數 date 調用 UNIX_TIMESTAMP(),它將傳回該參數值從 '1970-01-01 00:00:00' GMT 開始經過的秒數值。date 可以是一個 DATE 字串,一個 DATETIME 字串,一個 TIMESTAMP,或者以一個 YYMMDDYYYYMMDD 顯示的本地時間:
mysql> SELECT UNIX_TIMESTAMP();
        -> 882226357
mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
        -> 875996580
UNIX_TIMESTAMP 被用於一個 TIMESTAMP 列時,函數直接傳回一個內部的時間戳值,而不進行一個隱含地 “string-to-unix-timestamp” 轉換。 如果你傳遞一個超出範圍的日期參數給 UNIX_TIMESTAMP() ,它將傳回 0,但是請注意,MySQL 對其僅僅進行基本的檢驗(年範圍 1970-2037,月份 01-12,日期 01-31)。 如果你希望減去 UNIX_TIMESTAMP() 列,你應該需要將結果強制轉換為一有符號整數。查看章節 6.3.5 Cast 函數

FROM_UNIXTIME(unix_timestamp [,format])
'YYYY-MM-DD HH:MM:SS'YYYYMMDDHHMMSS 格式傳回一個 unix_timestamp 參數值,傳回值的形式取決於該函數使用於字串還是數位語境。 如果 format 給出,傳回值依 format 字串被格式。format 可以包含與 DATE_FORMAT() 函數同樣的修飾符。
mysql> SELECT FROM_UNIXTIME(875996580);
        -> '1997-10-04 22:23:00'
mysql> SELECT FROM_UNIXTIME(875996580) + 0;
        -> 19971004222300
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
                            '%Y %D %M %h:%i:%s %x');
        -> '1997 23rd December 03:43:30 1997'
SEC_TO_TIME(seconds)
'HH:MM:SS'HHMMSS 格式傳回參數 seconds 被轉換到時分秒後的值,傳回值的形式取決於該函數使用於字串還是數位語境:
mysql> SELECT SEC_TO_TIME(2378);
        -> '00:39:38'
mysql> SELECT SEC_TO_TIME(2378) + 0;
        -> 3938
TIME_TO_SEC(time)
將參數 time 轉換為秒數後傳回:
mysql> SELECT TIME_TO_SEC('22:23:00');
        -> 80580
mysql> SELECT TIME_TO_SEC('00:39:38');
        -> 2378

6.3.5 Cast 函數

CAST 函數的句法如下:

CAST(expression AS type)

或

CONVERT(expression,type)

type 可以是下面的任一個:

CAST() 是 ANSI SQL99 的句法,CONVERT() 是 ODBC 的句法。

CAST 函數主要用於以特殊的 CREATE ... SELECT 形式建立一個列時:

CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE);

CAST(string AS BINARYBINARY string 是相同的。 CAST(expr AS CHAR 表示一個使用目前預設字元集的字串。

為了將一個字串轉換成一個數位值,通常不需要做任何事情﹔只要將字串值當做一個數位即可:

mysql> SELECT 1+'1';
       -> 2

如果在一個字串語境中使用一個數位,該數位會被自動地轉換為一個 BINARY 字串。

mysql> SELECT CONCAT("hello you ",2);
       ->  "hello you 2"

MySQL 支援兩方是有符號的和無符號的 64 位值的算術運算。如果你使用一個數位運算子(比如 +),並且其中的一個操作數是 unsigned integer,那麼結果將是無符號的。為了不考慮這些問題,你可以使用 SIGNEDUNSIGNED CAST 運算子來,它會分別地強制運算到一個有符號的或一個無符號的 64 位整數。

mysql> SELECT CAST(1-2 AS UNSIGNED)
        -> 18446744073709551615
mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
        -> -1

注意,如果任一個操作數是一個浮點值(在這種語境下,DECIMAL() 被當作是一個浮點數值),結果也將是一個浮點數值,並且結果不受上面的規則影響。

mysql> SELECT CAST(1 AS UNSIGNED) -2.0
        -> -1.0

如果在一個算術運算中使用一個字串,它將被轉換為一個浮點數位。

函數 CAST()CONVERT() 在 MySQL 4.0.2 中被加入。

為了完全支援 BIGINT,在 MySQL 4.0 中對無符號值的處理發生了改變。如果希望你的代碼在 MySQL 4.0 和 3.23 中均能夠正常運行(在這種情況下,你或許不能夠使用 CAST 函數),當進行兩個無符號整數列的減法時,你可以使用下面的技巧得到一個有符號的結果:

SELECT (unsigned_column_1+0.0)-(unsigned_column_2+0.0);

這個做法是在進行減法之前,先將無符號列轉換為一個浮點數。

如果你將舊的 MySQL 應用程式移植到 MySQL 4.0 時,在 UNSIGNED 列上出現了問題,你可以在啟動 mysqld 時使用 --sql-mode=NO_UNSIGNED_SUBTRACTION 選項。注意,只要你使用了這個選項,你將不能直接地使用 UNSIGNED BIGINT 列類型。

6.3.6 其它函數

6.3.6.1 位函數

MySQL 使用 BIGINT (64 位) 算法進行位運算,因而這些運算子有一個 64 位的最大範圍。

|
位或
mysql> SELECT 29 | 15;
        -> 31
傳回值是一個 64 位的無符號整數。

&
位與
mysql> SELECT 29 & 15;
        -> 13
傳回值是一個 64 位的無符號整數。

^
位異或
mysql> SELECT 1 ^ 1;
        -> 0
mysql> SELECT 1 ^ 0;
        -> 1
mysql> SELECT 11 ^ 3;
        -> 8
傳回值是一個 64 位的無符號整數。 XOR 在 MySQL 4.0.2 中被加入。

<<
左移一個長長的數位(BIGINT):
mysql> SELECT 1 << 2;
        -> 4
傳回值是一個 64 位的無符號整數。

>>
右移一個長長的數位(BIGINT):
mysql> SELECT 4 >> 2;
        -> 1
傳回值是一個 64 位的無符號整數。

~
置反所有位:
mysql> SELECT 5 & ~1;
        -> 4
傳回值是一個 64 位的無符號整數。

BIT_COUNT(N)
傳回在參數 N 中內嵌的比特位數量:
mysql> SELECT BIT_COUNT(29);
        -> 4

6.3.6.2 輔助功能函數

DATABASE()
傳回目前資料庫名:
mysql> SELECT DATABASE();
        -> 'test'
如果沒有目前資料庫,DATABASE() 傳回一個空字串。
USER()
SYSTEM_USER()
SESSION_USER()
傳回目前 MySQL 使用者名:
mysql> SELECT USER();
        -> 'davida@localhost'
在 MySQL 3.22.11 或更新的版本中,傳回值包含使用者名和客戶機的主機名。你可以象下面所示的僅取出使用者名部分(無論值是否包含一個主機名部分,它均能正常工作):
mysql> SELECT SUBSTRING_INDEX(USER(),"@",1);
        -> 'davida'
CURRENT_USER()
傳回目前會話被驗証相符的使用者名:
mysql> SELECT USER();
        -> 'davida@localhost'
mysql> SELECT * FROM mysql.user;
        -> ERROR 1044: Access denied for user: '@localhost' to database 'mysql'
mysql> SELECT CURRENT_USER();
        -> '@localhost'
PASSWORD(str)
OLD_PASSWORD(str)
從純純文字密碼 str 計算一個密碼字串。這個函數用於對儲存到授權表 userPassword 列中的 MySQL 密碼進行加密。
mysql> SELECT PASSWORD('badpwd');
        -> '7f84554057dd964b'
PASSWORD() 加密是不可逆的。 PASSWORD() 不以與 Unix 密碼加密相同的方式進行密碼加密。參見 ENCRYPT()注意, PASSWORD() 函數是用於在 MySQL 服務中驗証系統的,你不應該 在你的應用程式中使用它。你可以使用 MD5()SHA1() 代替使用它。同樣查看 RFC-2195 可獲得有關應用程式的密碼處理與安全驗証的更多資訊。
ENCRYPT(str[,salt])
Encrypt使用 Unix crypt() 系統調用加密 str 。參數 salt 應該是一個有兩個字元的字串,(在 MySQL 3.22.16 中,salt 可以超過兩個字元。):
mysql> SELECT ENCRYPT("hello");
        -> 'VxuFAJXVARROc'
如果 crypt() 在你的系統上不可用,ENCRYPT() 總是傳回 NULLENCRYPT() 只保留 str 中前 8 個字元,而忽略其它所有的,至少在某些系統上是這樣的。這取決於底層 crypt() 系統調用的行為。

ENCODE(str,pass_str)
使用 pass_str 做為密鑰加密 str。使用 DECODE() 解密結果。結果是一個與 string 一樣長的二進位字元。如果希望將它保存到一個列中,請使用 BLOB 列類型。

DECODE(crypt_str,pass_str)
使用 pass_str 作為密鑰解密加密後的字串 crypt_strcrypt_str 應該是一個由 ENCODE() 傳回的字串。

MD5(string)
計算一個字串的 MD5 128 位校驗和。值作為一個 32 位的十六進制數位傳回,例如,被用於一個哈希(hash)鍵:
mysql> SELECT MD5("testing");
        -> 'ae2b1fca515949e5d54fb22b8ed95575'
這是 "RSA 資料安全公司的 MD5 訊息-摘要算法"。

SHA1(string)
SHA(string)
計算一個字串的 SHA1 160 位校驗和(在 RFC 3174 (Secure Hash Algorithm) 中被描述)。傳回值是一個 40 位的十六進制數位,或在輸入參數為 NULL 的情況下,傳回值為 NULL。一個使用這個函數的可能就是用於一個哈希鍵。你也可以使用它作為儲存密碼時的密碼安全函數。
mysql> SELECT SHA1("abc");
        -> 'a9993e364706816aba3e25717850c26c9cd0d89d'
SHA1() 在MySQL 4.0.2 中被加入,並可被當做比 MD5() 加密更安全的等價物。SHA()SHA1() 的同義詞。

AES_ENCRYPT(string,key_string)
AES_DECRYPT(string,key_string)
這些函數允許使用官方的 AES(Advanced Encryption Standardadvanced 先進的密碼技術標準) 算法加密/解密資料。加密時使用 128 位長的密鑰,但是你可以通過修改源碼將其擴展到 256 位。我們選擇 128 位是因為它更快一點並且已足夠安全了。 輸入的參數可以是任意長度的。如果任何一個參數是 NULL,這個函數傳回值也將是 NULL。 因為 AES 是一個塊級的算法,加密不同長度的字串時會對其進行填充,因而結果字串的長度也可以通過 16*(trunc(string_length/16)+1) 計算出。 如果 AES_DECRYPT() 發現資料無效或錯誤的填料,它將傳回 NULL。可是,如果輸入的資料或密鑰是無效的,函數仍然可能傳回一個非 NULL 值 (可能是無用的資訊)。 通過修改你的 SQL 語句,你可以使用 AES 函數以一個加密的形式儲存資料:
INSERT INTO t VALUES (1,AES_ENCRYPT("text","password"));
盡量避免在一個連線上的每個查詢中傳遞密鑰,這樣可以得到更高的安全性,上述方式可以通過連線時在伺服器端儲存密鑰來完成:
SELECT @password:="my password";
INSERT INTO t VALUES (1,AES_ENCRYPT("text",@password));
AES_ENCRYPT()AES_DECRYPT() 在 MySQL 4.0.2 中被加入,可以被考慮為目前 MySQL 中可用的加解密函數中最密碼安全的。

DES_ENCRYPT(string_to_encrypt [, (key_number | key_string) ] )
使用 Triple-DES 算法以給定的密鑰對字串加密。 注意,只有配置了 MySQL 對 SSL 的支援,這個函數才能正常工作。查看章節 4.3.9 使用安全地連線。 編碼密鑰以下列各項方法選擇:
參數 含義
只有一個參數 des-key-file 中的第一個密鑰被使用。
key number des-key-file 中給定的密鑰 (0-9) 被使用。
string 給定的 key_string 將被用於加密 string_to_encrypt
傳回字串是一個二進位字串,並且第一個字元是 CHAR(128 | key_number)。 128 被加入是為了更加容易地辨識一個加密密鑰。如果你使用一個字串密鑰,key_number 將是 127。 當發生錯誤時,這個函數傳回 NULL。 傳回字串的長度將為:new_length= org_length + (8-(org_length % 8))+1des-key-file 的格式如下:
key_number des_key_string
key_number des_key_string
每個 key_number 必須是一個在 0 到 9 範圍之內的數位。文件中的行可以是任何次序的。des_key_string 是用於加密訊息的字串。在數位與密鑰之間至少要有一個空格。如果你沒在 DES_ENCRYPT() 指定任何密鑰參數,那麼文件中的第一個密鑰將被預設使用。 以 FLUSH DES_KEY_FILE 命令,你可以告訴 MySQL 從密鑰文件中讀取新的密鑰值。這個操作需要你有 Reload_priv 權限。 有一套預設密鑰的一個好處就是,它給應用程式一個檢查存在的加密列值的方法,而不需要給最終使用者解密這些值的權限。
mysql> SELECT customer_address FROM customer_table WHERE
       crypted_credit_card = DES_ENCRYPT("credit_card_number");
DES_DECRYPT(string_to_decrypt [, key_string])
解密 DES_ENCRYPT() 加密後的字串。 注意,只有配置了 MySQL 對 SSL 的支援,這個函數才能正常工作。查看章節 4.3.9 使用安全地連線。 如果 key_string 參數沒有給出,DES_DECRYPT() 檢查加密字串的第一個字節,以確定用於加密原始字串的 DES 密鑰數位,然後從 des-key-file 讀取密鑰用於解密訊息。為了能這樣工作,該使用者必須有 SUPER 權限。 如果將一個 key_string 參數傳遞給該函數,這個字串將被作為解密訊息的密鑰。 如果 string_to_decrypt 看上去不像是一個加密字串,MySQL 將傳回給定的 string_to_decrypt。 當發生錯誤時,該函數傳回 NULL

LAST_INSERT_ID([expr])
傳回被插入到一個 AUTO_INCREMENT 列中的最後一個自動產生的值。查看章節 8.1.3.130 mysql_insert_id()
mysql> SELECT LAST_INSERT_ID();
        -> 195
最後產生的 ID 是以每個連線為基礎在伺服器端被維護的。它不可能被其它的客戶端連線改變。如果你以一個非特殊值(即一個非 NULL 和非 0 的值)更新其它的 AUTO_INCREMENT,它甚至也不會改變。 如果你在同一時間內以一個插入語句插入了許多記錄行,LAST_INSERT_ID() 將傳回第一個被插入行的值。這樣做的原因是因為,這可能列容易地在其它伺服器上再現同一條 INSERT 語句。 如果 expr 被作為一個參數傳遞給 LAST_INSERT_ID(),那麼函數將傳回這個參數的值,並且被設定為 LAST_INSERT_ID() 傳回的下一個值。這可被用於模擬一個序列: 首先建立一個表:
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
然後這個表可以被用來以下面的方式產生序列值:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
你也可以不調用 LAST_INSERT_ID() 產生序列,但是以這種方式使用這個函數的作用就是,ID 值是在伺服器端敘談最後的自動產生值被維護的(是多使用者安全的)。你可以檢索這的新的 ID 值,就好像讀取 MySQL 中任何正常的 AUTO_INCREMENT 值一樣。舉例來說,LAST_INSERT_ID()(無任何參數) 將傳回一個新的 ID。C API 函數 mysql_insert_id() 也可以用來得到這個值。 注意,由於 mysql_insert_id() 僅僅只能用於在 INSERTUPDATE 語句的更新之後,所以在執行了其它的 SQL 語句(比如 SELECTSET)之後,你不能夠使用 C API 函數檢索到 LAST_INSERT_ID(expr) 的值。

FORMAT(X,D)
將數位 X 格式化為一個 '#,###,###.##' 的形式,四舍五入到 D 位小數。如果 D0,傳回的結果將沒有小數點和小數部分:
mysql> SELECT FORMAT(12332.123456, 4);
        -> '12,332.1235'
mysql> SELECT FORMAT(12332.1,4);
        -> '12,332.1000'
mysql> SELECT FORMAT(12332.2,0);
        -> '12,332'
VERSION()
以一個字串形式傳回 MySQL 伺服器的版本:
mysql> SELECT VERSION();
        -> '3.23.13-log'
注意,如果你的版本以 -log 結果,那就意味著日誌是被設為可用的。

CONNECTION_ID()
傳回目前連線的連線 ID(thread_id)。每個連線均有一個自己唯一的 id:
mysql> SELECT CONNECTION_ID();
        -> 1
GET_LOCK(str,timeout)
嘗試獲得一個由字串 str 給定名字的鎖定與一個 timeout 秒的逾時。如果鎖定被獲得成功,傳回 1,如果嘗試逾時,傳回 0,或者一個錯誤發生(比如記憶體溢出或線程被 mysqladmin kill 殺死),傳回NULL。當你執行 RELEASE_LOCK()、執行一個新的 GET_LOCK(),或線程終止時,一個鎖定被釋放。這個函數可以被用於執行應用程式鎖定或模擬記錄鎖定。它會阻塞其它的客戶端用同樣的名字的鎖定請求﹔遵從一個給定鎖定字串名的客戶端可以使用這個字串來執行幾協作建議的鎖定:
mysql> SELECT GET_LOCK("lock1",10);
        -> 1
mysql> SELECT IS_FREE_LOCK("lock2");
        -> 1
mysql> SELECT GET_LOCK("lock2",10);
        -> 1
mysql> SELECT RELEASE_LOCK("lock2");
        -> 1
mysql> SELECT RELEASE_LOCK("lock1");
        -> NULL
注意,第二個 RELEASE_LOCK() 調用傳回 NULL 是因為 "lock1" 鎖定被第二個 GET_LOCK() 調用自動地釋放了。

RELEASE_LOCK(str)
釋放由字串 str 命名的通過 GET_LOCK() 獲得的鎖定。如果鎖定被釋放,傳回 1﹔如果鎖定並沒有被目前線程鎖定(在這種情況下,鎖定不會被釋放),傳回 0﹔如果命名的鎖定不存在,傳回 NULL。如果鎖定從來就沒有通過調用一個 GET_LOCK() 獲得,或已被釋放了,那麼該鎖定將不存在。 DO 語句通常與 RELEASE_LOCK() 一起使用。查看章節 6.4.10 DO 句法

IS_FREE_LOCK(str)
檢查以 str 命名的鎖定是否可以自由使用(也就是說,還未鎖定)。如果鎖定被釋放了(沒有一個人使用這個鎖定),傳回 1﹔如果這個鎖定處於使用中,傳回 0﹔如果發生一個錯(例如錯誤的參數),傳回 NULL

BENCHMARK(count,expr)
BENCHMARK() 函數用於將表達式 expr 重復運行 count 次。它可以被用於計時 MySQL 處理表達式有多快。結果通常為 0。在 mysql 客戶端有意使用它時,它將傳回查詢執行所需的時間:
mysql> SELECT BENCHMARK(1000000,ENCODE("hello","goodbye"));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE("hello","goodbye")) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)
報告的時間是客戶端經過的時間,不是伺服器端的 CPU 時間。執行 BENCHMARK() 多次可能是明智的,並注意伺服器的負載來解釋結果。

INET_NTOA(expr)
給定一個數位的網路位址 (4 或 8 字節),以一個字串的形式傳回點組表示的位址:
mysql> SELECT INET_NTOA(3520061480);
       ->  "209.207.224.40"
INET_ATON(expr)
以字串的形式給定一個點組表示的網路位址,傳回一個位址的數位值表示的整數。位址可以是 4 或 8 個字節的位址:
mysql> SELECT INET_ATON("209.207.224.40");
       ->  3520061480
產生的數位通常是以網路位址字節的順序﹔例如,上面的數位是以 209*256^3 + 207*256^2 + 224*256 +40 被計算出來的。

MASTER_POS_WAIT(log_name, log_pos)
阻塞,只到從伺服器到達(也就是說,已讀取並應用了所有更新,一直到)主伺服器上的日誌中指定的位置。 如果主伺服器上的資訊沒有初始化,或如果參數錯誤,傳回 NULL。如果從伺服器沒有運行,將阻塞並造作,只到它啟動並到達或超過指定的位置。如果從伺服器已超過指定的位置,立即傳回。 如果 timeout (在 4.0.10 中新加入) 被指定,當等待 timeout 秒經過後,將放棄。timeout 必須大於 0﹔一個零或一個負值 timeout 意味著逾時。 傳回值是到達日誌指定位置所必須等待的日誌事件的數量,或者在出錯的情況下為 NULL,或者超過逾時時間傳回 -1。 這個命令有益於控制主從伺服器的同步,但是最初是為了復制測試的方便而寫的。

FOUND_ROWS()
傳回最後一個 SELECT SQL_CALC_FOUND_ROWS ... 命令如果沒有以 LIMIT 進行限制結果時將傳回記錄行數。
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
       WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
第二個 SELECT 將傳回一個數位,它指示前一個沒有被 LIMIT 幾句限制的 SELECT 將傳回多少行記錄。注意,如果你使用 SELECT SQL_CALC_FOUND_ROWS ...,MySQL 不得不計算所有的記錄行到結果集中。然而,這與你不使用 LIMIT 相比是更快一點的,因為結果集不需要發送到客戶端。 SQL_CALC_FOUND_ROWS 從 MySQL 4.0.0 開始可以被使用。

6.3.7 用於 GROUP BY 幾句的函數

如果在一個沒有包含 GROUP BY 幾句的一個語句中使用聚合函數,它將等價於將所有的記錄行分為一組。

COUNT(expr)
傳回由一個 SELECT 語句檢索出來的記錄行中非 NULL 值的記錄總數目:
mysql> SELECT student.student_name,COUNT(*)
    ->        FROM student,course
    ->        WHERE student.student_id=course.student_id
    ->        GROUP BY student_name;

COUNT(*) 在它傳回檢索出的記錄行的數目上稍微有點不同,它不管記錄行中是否包括 NULL 值。 如果 SELECT 語句從一個表中進行檢索,沒有檢索其它的列,並且沒有 WHERE 幾句,那麼 COUNT(*) 將被最佳化以便更快地傳回值。範例如下:
mysql> SELECT COUNT(*) FROM student;
COUNT(DISTINCT expr,[expr...])
傳回一個互不相同的非 NULL 的值的總數目:
mysql> SELECT COUNT(DISTINCT results) FROM student;
在 MySQL 中,通過給出一個表達式清單,可以得到不包含 NULL 的不同的表達式組合的數目。在 ANSI SQL 中,你可能不得不在 COUNT(DISTINCT ...) 中拼接所有的表達式。

AVG(expr)
傳回 expr 的平均值:
mysql> SELECT student_name, AVG(test_score)
    ->        FROM student
    ->        GROUP BY student_name;
MIN(expr)
MAX(expr)
傳回 expr 的最小或最大值。MIN()MAX() 可以接受一個字串參數﹔在這種情況下,它們將傳回最小或最大的字串傳下。查看章節 5.4.3 MySQL 如何使用索引
mysql> SELECT student_name, MIN(test_score), MAX(test_score)
    ->        FROM student
    ->        GROUP BY student_name;
MIN()MAX() 和其它的合計函數中,MySQL 通常列的字串值比較 ENUMSET 列,而不是字串在集合中相對應的位置。這將會被修正。
SUM(expr)
傳回 expr 的總和。注意,如果傳回集中沒有從我任何記錄行,它將傳回 NULL !

GROUP_CONCAT(expr)
完整句法如下:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]]
             [SEPARATOR str_val])
這個函數在 MySQL 4.1 中被加入。函數傳回一個字串結果,該結果由分組中的值連線組合而成:
mysql> SELECT student_name,
    ->        GROUP_CONCAT(test_score)
    ->        FROM student 
    ->        GROUP BY student_name;
or
mysql> SELECT student_name,
    ->        GROUP_CONCAT(DISTINCT test_score
    ->                     ORDER BY test_score DESC SEPARATOR " ")
    ->        FROM student
    ->        GROUP BY student_name;
在 MySQL 中,你可以得到表達式結合體的連結值。通過使用 DISTINCT 可以排除重復值。如果希望對結果中的值進行排序,可以使用 ORDER BY 幾句。為了以倒序排序,可以在 ORDER BY 幾句中用於排序的列名後加入一個 DESC (遞減 descending) 關鍵詞。預設為升序﹔這也可以通過使用 ASC 關鍵詞明確指定。 SEPARATOR 是一個字串值,它被用於插入到結果值中。預設為一個逗號 (",")。你可以通過指定 SEPARATOR "" 完全地移除這個分隔符。 在你的配置中,通過變數 group_concat_max_len 要以設定一個最大的長度。在運行時執行的句法如下:
SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
如果最大長度被設定,結果值被剪下到這個最大長度。 GROUP_CONCAT() 函數是一個增強的 Sybase SQL Anywhere 支援的基本 LIST() 函數。 如果只有一個列,並且沒有其它選項被指定,GROUP_CONCAT() 是向後兼容有極大限制的 LIST() 函數。 LIST() 有一個預設的排序次序。

範例(譯者注):

mysql> CREATE TABLE `ta` (
    ->   `id` smallint(5) unsigned NOT NULL default '0',
    ->   `name` char(60) NOT NULL default '',
    ->   KEY `id` (`id`)
    -> ) TYPE=MyISAM;
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO `ta` VALUES("1", "a"),("1", "b"),
    ->     ("1", "c"),("1", "d"),("2", "a"),
    ->     ("2", "b"),("2", "c"),("3", "d");
Query OK, 8 rows affected (0.03 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM `ta`;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  1 | b    |
|  1 | c    |
|  1 | d    |
|  2 | a    |
|  2 | b    |
|  2 | c    |
|  3 | d    |
+----+------+
8 rows in set (0.00 sec)

mysql> SELECT `id`,
    ->   GROUP_CONCAT(`name`)
    ->   FROM `ta`
    ->   GROUP BY `id`;
+----+----------------------+
| id | GROUP_CONCAT(`name`) |
+----+----------------------+
|  1 | a c b d              |
|  2 | a c b                |
|  3 | d                    |
+----+----------------------+
3 rows in set (0.03 sec)

# SEPARATOR 預設是一個空格而不是一個逗號

mysql> SELECT `id`,
    ->   GROUP_CONCAT(DISTINCT `name`
    ->                ORDER BY `name` DESC SEPARATOR ",") AS Result
    ->   FROM `ta`
    ->   GROUP BY `id`;
+----+---------+
| id | Result  |
+----+---------+
|  1 | d,c,b,a |
|  2 | c,b,a   |
|  3 | d       |
+----+---------+
3 rows in set (0.00 sec)

* 以上結果在 MySQL 4.1 中測試
範例結束(譯者注)

VARIANCE(expr)
傳回 expr 的標準方差(standard variance)。這是對 ANSI SQL 的擴展(只有在 4.1 或更新的版本中可用)。

STD(expr)
STDDEV(expr)
傳回 expr 的標準偏差(standard deviation)。這是對 ANSI SQL 的擴展。這個函數的 STDDEV() 格式是為了 Oracle 兼容而提供的。

BIT_OR(expr)
傳回 expr 中所有比特位的位 OR。計算以 64 位 (BIGINT) 精度執行。

BIT_AND(expr)
傳回 expr 中所有比特位的位 AND。計算以 64 位 (BIGINT) 精度執行。

範例(譯者注):


mysql> CREATE TABLE `ta` (
    ->   `id` smallint(5) unsigned NOT NULL default '0',
    ->   KEY `id` (`id`)
    -> ) TYPE=MyISAM;
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO `ta` VALUES("1"),("2"),("3"),("4");
Query OK, 8 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SELECT BIT_OR(id) from ta;
+------------+
| BIT_OR(id) |
+------------+
|          7 |
+------------+
1 row in set (0.00 sec)

#     ..0001
#     ..0010
#     ..0011
#     ..0100
#  OR ..0000
#  ---------
#     ..0111

mysql> SELECT BIT_AND(id) from ta;
+-------------+
| BIT_AND(id) |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)

#      ..0001
#      ..0010
#      ..0011
#      ..0100
#  AND ..1111
#  ----------
#      ..0000

* 以上結果在 MySQL 4.1 中測試
範例結束(譯者注)

MySQL 擴展了 GROUP BY 的用法。在 SELECT 表達式中,你可以使用或計算沒有出現在 GROUP BY 部分中的列。這代表 這個組的任何可能的值。 你可以使用它避免在不必要的分類項目上進行排序和分組,這樣會得到更好的性能。 舉例來說,在下面的範例中,你不必要以 customer.name 進行分組:

mysql> SELECT order.custid,customer.name,MAX(payments)
    ->        FROM order,customer
    ->        WHERE order.custid = customer.custid
    ->        GROUP BY order.custid;

在 ANSI SQL 中,必須將customer.name 加入到 GROUP BY 幾句。而在 MySQL 中,如果沒有以 ANSI 樣式運行,該名是多餘的。

如果你在 GROUP BY 部分省略的列在分組中不是唯一的,請不要使用這個特征!否則將得到不可預知的結果。

在某些情況下,可以使用 MIN()MAX() 獲得一個特定的列值,即使它不是唯一的。 下面的範例取出包含了 sort 列中最小值的記錄行中的 column 的值:

SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7)

查看章節 3.5.4 擁有某個欄位的組間最大值的記錄行

注意,如果你所使用的是 MySQL 3.22 (或更早的版本),或者你正試圖遵從 ANSI SQL,你不能在 GROUP BYORDER BY 幾句中使用表達式。你可以使用表達式的別名來應付這個限制:

mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name
    ->        GROUP BY id,val ORDER BY val;

在 MySQL 3.23 中,你可以這樣做:

mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();