(MariaDB)MySQL內置函數大全

本文目錄:
1. 字符串函數
 1.1 字符串鏈接函數
 1.2 lower()、upper()、left()、right()
 1.3 填充函數lpad()和rpad()
 1.4 trim()、ltrim()、rtrim()及trim()
 1.5 字符串重複函數repeat()
 1.6 字符串替換函數replace()
 1.7 字符串插入替換函數insert()
 1.8 字符串提取substring()
 1.9 字符串比較函數strcmp()
 1.10 字符串長度函數length()和char_length()
 1.11 字符串位置函數locate()、position()和instr()
 1.12 字符串位置函數find_in_set()
 1.13 字符串位置函數field()
 1.14 指定位置的字符串函數elt()
 1.15 字符串反轉函數reverse()
2. 數學函數
 2.1 絕對值函數ABS()
 2.2 取模函數mod()
 2.3 四捨五入函數round()
 2.4 位數截斷函數truncate()
 2.5 地板函數floor()和天花板函數ceiling()
 2.6 隨機函數rand()
 2.7 最值函數least()
 2.8 最值函數greatest()
3. 日期時間函數
 3.1 當前日期時間
 3.2 week()
 3.3 year()、monthname()、quarter()
 3.4 hour()、minute()、second()
 3.5 extract()
 3.6 dayname()和dayofweek()
 3.7 日期時間格式化
 3.8 日期時間計算
 3.9 datediff()
 3.10 LAST_DAY()
4. 流程控制之條件判斷函數
 4.1 if()
 4.2 ifnull()
 4.3 nullif()
 4.4 case語句
5. 類型轉換函數
6. 其它實用函數 javascript

MySQL/MariaDB的內置函數比較多,這裏挑選一部分進行解釋,完整的內置函數列表見官方手冊php

1. 字符串函數

完整的內置字符串函數見官方手冊css

1.1 字符串鏈接函數

有兩個字符串鏈接函數:concat(s1,s2,s3,...,sN)和concat_ws(sep,s1,s2,s3,...,sN)。html

concat()將多個字符串鏈接起來造成一個長字符串。它會嘗試將字符所有轉換爲字符型,若是存在null,則直接返回null。java

mysql> select concat('a','b',1),concat(1,2,3),concat('a',null);
+-------------------+---------------+------------------+
| concat('a','b',1) | concat(1,2,3) | concat('a',null) |
+-------------------+---------------+------------------+
| ab1               | 123           | NULL             |
+-------------------+---------------+------------------+
1 row in set

concat_ws(sep,s1,s2,...,sN)函數是concat()函數的特殊格式,它的第一個參數sep是用於鏈接s1,s2,...,sN的分隔符。分隔符能夠是一個字符或一個字符串,只要合理便可。若是分隔符sep爲null,則返回結果null,若是s1,s2,...,sN之間出現了null,則忽略null。mysql

mysql> select concat_ws(':','23','59','58'),concat_ws('-','1st','2nd'),concat_ws('XXX','wo','shi');
+-------------------------------+----------------------------+-----------------------------+
| concat_ws(':','23','59','58') | concat_ws('-','1st','2nd') | concat_ws('XXX','wo','shi') |
+-------------------------------+----------------------------+-----------------------------+
| 23:59:58                      | 1st-2nd                    | woXXXshi                    |
+-------------------------------+----------------------------+-----------------------------+
1 row in set

mysql> select concat_ws(':','23','59',null,'58'),concat_ws(null,'1st','2nd');
+------------------------------------+-----------------------------+
| concat_ws(':','23','59',null,'58') | concat_ws(null,'1st','2nd') |
+------------------------------------+-----------------------------+
| 23:59:58                           | NULL                        |
+------------------------------------+-----------------------------+
1 row in set

因爲concat()遇到null時總會返回null,這種處理方式可能並不是所指望的結果,所以能夠採用concat_ws()的方式忽略null或者採用ifnull()的方式將null轉換爲空字符串。nginx

1.2 lower(string)、upper(string)、left(string,x)、right(string,x)

分別是變小寫、變大寫、從左取x長度字符、從右取x長度字符git

mysql> select lower('MaLong'),upper('MaLong'),left('MaLong',3),right('Malong',3);
+-----------------+-----------------+------------------+-------------------+
| lower('MaLong') | upper('MaLong') | left('MaLong',3) | right('Malong',3) |
+-----------------+-----------------+------------------+-------------------+
| malong          | MALONG          | MaL              | ong               |
+-----------------+-----------------+------------------+-------------------+
1 row in set

1.3 填充函數

有兩種:lpad(string,n,pad)和rpad(string,n,pad)。github

使用pad對string最左邊和最右邊進行填充,直到填充後總長度爲n個字符。pad能夠是一個字符串,若是是字符串則從左向右取直到符合長度爲止。web

mysql> select lpad('MaLong',10,'x'),lpad('MaLong',10,'xy'),rpad('MaLong',10,'x');
+-----------------------+------------------------+-----------------------+
| lpad('MaLong',10,'x') | lpad('MaLong',10,'xy') | rpad('MaLong',10,'x') |
+-----------------------+------------------------+-----------------------+
| xxxxMaLong            | xyxyMaLong             | MaLongxxxx            |
+-----------------------+------------------------+-----------------------+
1 row in set

長度n能夠是小於或等於string字符串長度的值,此時lpad或者rpad的做用都是從左進行字符串截取而非填充,直到長度爲n。也就是說lpad和rpad函數最強約束條件是長度參數n。

mysql> select rpad('MaLong',3,'x'),lpad('MaLong',3,'x'),lpad('MaLong',0,'x');
+----------------------+----------------------+----------------------+
| rpad('MaLong',3,'x') | lpad('MaLong',3,'x') | lpad('MaLong',0,'x') |
+----------------------+----------------------+----------------------+
| MaL                  | MaL                  |                      |
+----------------------+----------------------+----------------------+
1 row in set

1.4 trim(string)、ltrim(string)、rtrim(sting)及trim(substring from string)

分別用來消除string行首和行尾、行首、行尾的空格以及行首行尾指定的字符串。

函數                    做用
-----------------------         -------------------------------
      ltrim(string)             刪除行首空格
      rtrim(string)             刪除行尾空格
      trim(string)              刪除行首和行尾空格
trim(substring from string)     刪除行首和行尾的字符串substring

例如:

mysql> select length(trim(' MaLong ')) as A, length(ltrim('MaLong ')) as B, length(ltrim(' MaLong ')) as C, length(rtrim(' MaLong ')) as D;
+---+---+---+---+
| A | B | C | D |
+---+---+---+---+
| 6 | 7 | 7 | 7 |
+---+---+---+---+
1 row in set (0.00 sec) mysql> select trim('xy' from 'xyxabxycdxyxy');
+---------------------------------+
| trim('xy' from 'xyxabxycdxyxy') |
+---------------------------------+
| xabxycd                         |
+---------------------------------+
1 row in set

1.5 重複字符串repeat(string,x)

將string重複x次。

mysql> select repeat('xy',3),length(repeat(' ',3)),repeat('0',3);
+----------------+-----------------------+---------------+
| repeat('xy',3) | length(repeat(' ',3)) | repeat('0',3) |
+----------------+-----------------------+---------------+
| xyxyxy         |                     3 | 000           |
+----------------+-----------------------+---------------+
1 row in set

1.6 字符串替換函數replace(string,a,b)

使用字符串b替換字符串string中全部的字符串a。注意點是它們均可以是字符串。若是想要替換掉的字符串a不在string中,則不會進行替換。

mysql> select replace('woshiMaLongShuai','s','xxxx'),replace('woshiMaLongShuai','ob','xxxx');
+----------------------------------------+-----------------------------------------+
| replace('woshiMaLongShuai','s','xxxx') | replace('woshiMaLongShuai','ob','xxxx') |
+----------------------------------------+-----------------------------------------+
| woxxxxhiMaLongShuai                    | woshiMaLongShuai                        |
+----------------------------------------+-----------------------------------------+
1 row in set

1.7 字符串插入替換函數insert(string,p1,len,instead_string)

將string從位置p1開始,len個長度的字符替換爲instead_string。

mysql> select insert('woshimalongshuai',6,2,'gao');
+--------------------------------------+
| insert('woshimalongshuai',6,2,'gao') |
+--------------------------------------+
| woshigaolongshuai                    |
+--------------------------------------+
1 row in set

1.8 字符串提取substring(string,x,y)

返回string中從x位置開始y個長度的字符串。若是給出的位置不存在,則沒法提取因此返回空。若是給出的長度超出,則只提取容許範圍內的字符串。

mysql> select substring('MaLo',3,4) AS A,substring('MaLo',0,4) AS B,substring('MaLo',10,4) AS C,length(substring('MaLo',3,10)) AS D;
+----+---+---+---+
| A  | B | C | D |
+----+---+---+---+
| Lo |   |   | 2 |
+----+---+---+---+
1 row in set (0.00 sec)

1.9 字符串比較函數strcmp(string1,string2)

比較string1和string2的ascii碼大小,從前向後依次比較。strcmp認爲大小寫字母是等價的,因此它們相等。且存在null時,直接返回null。

  • 若是string1小於string2,返回-1。
  • 若是string1等於string2,返回0。
  • 若是string1大於string2,返回1。
mysql> select strcmp('a','b'),strcmp('a','A'),strcmp('b','a');
+-----------------+-----------------+-----------------+
| strcmp('a','b') | strcmp('a','A') | strcmp('b','a') |
+-----------------+-----------------+-----------------+
|              -1 |               0 |               1 |
+-----------------+-----------------+-----------------+
1 row in set
mysql> select strcmp('ac','ab'),strcmp('ac','ac'),strcmp('a',null),strcmp(null,'a');
+-------------------+-------------------+------------------+------------------+
| strcmp('ac','ab') | strcmp('ac','ac') | strcmp('a',null) | strcmp(null,'a') |
+-------------------+-------------------+------------------+------------------+
|                 1 |                 0 | NULL             | NULL             |
+-------------------+-------------------+------------------+------------------+
1 row in set

關於字符串比較,另外兩個函數least()和greatest()也能實現,這兩個函數更多的用於取最值,特別是用於數值比較,因此在後文解釋。

1.10 字符串長度函數length(string)和char_length(string)

length()返回字符串的字節數,注意不是字符數,char_length()返回的纔是字符數。在SQL Server中長度函數是len(string),且返回的是字符數。

mysql> select length('woshiyigeren'),length('我');
+------------------------+--------------+
| length('woshiyigeren') | length('我') |
+------------------------+--------------+
|                     12 |            3 |
+------------------------+--------------+
1 row in set

mysql> select char_length('woshiyigeren'),char_length('我');
+-----------------------------+-------------------+
| char_length('woshiyigeren') | char_length('我') |
+-----------------------------+-------------------+
|                          12 |                 1 |
+-----------------------------+-------------------+
1 row in set

在SQL Server中:

1.11 字符串位置函數locate(sub_str,string)、position(sub_str in string)和instr(str,sub_str)

這三個函數的做用相同,都是返回sub_str在string中的開始位置。和SQL Server中的charindex()函數功能相似。

mysql> SELECT LOCATE('ball','football'),POSITION('ball' IN 'football') ,INSTR('football','ball');
+---------------------------+--------------------------------+--------------------------+
| LOCATE('ball','football') | POSITION('ball' IN 'football') | INSTR('football','ball') |
+---------------------------+--------------------------------+--------------------------+
|                         5 |                              5 |                        5 |
+---------------------------+--------------------------------+--------------------------+
1 row in set

1.12 字符串位置函數find_in_set(sub_string,str_set)

返回子串sub_string在str_set中的位置,其中str_set是一個由逗號隔開的多個字符串集合。若是找不到位置(sub_str不在str_set中或者str_set爲空串)則返回0,若是任意一個爲null,則返回null。

mysql> select find_in_set('ab','cd,ab,dc'),find_in_set('ab',''),find_in_set(null,'ab,cd');
+------------------------------+----------------------+---------------------------+
| find_in_set('ab','cd,ab,dc') | find_in_set('ab','') | find_in_set(null,'ab,cd') |
+------------------------------+----------------------+---------------------------+
|                            2 |                    0 | NULL                      |
+------------------------------+----------------------+---------------------------+
1 row in set

1.13 字符串位置函數field(s,str1,str2,...,strN)

返回字符串s在字符串集合str1,str2,...,strN中的位置。若是找不到或者字符串s爲null,則返回0,由於null沒法進行比較,也就是找不到。

mysql> select field('ab','abc','1ab','ab','cd') as col1,field(null,'ab','cd') as col2;
+------+------+
| col1 | col2 |
+------+------+
|    3 |    0 |
+------+------+
1 row in set (0.00 sec)

1.14 指定位置的字符串函數elt(n,str1,str2,...,strN)

elt表示從(數據)倉庫中提取須要的東西。n是位置,n=1則返回str1,n=2則返回str2,依次類推。當n<1或者大於字符串的數量,則返回null。

mysql> select elt(1,'a','b','c'),elt(2,'a','b','c'),elt(0,'a','b'),elt(10,'a','b');
+--------------------+--------------------+----------------+-----------------+
| elt(1,'a','b','c') | elt(2,'a','b','c') | elt(0,'a','b') | elt(10,'a','b') |
+--------------------+--------------------+----------------+-----------------+
| a                  | b                  | NULL           | NULL            |
+--------------------+--------------------+----------------+-----------------+
1 row in set

1.15 字符串反轉函數reverse(str)

反轉字符串str的字符順序。

mysql> select reverse('hello');
+------------------+
| reverse('hello') |
+------------------+
| olleh            |
+------------------+
1 row in set (0.00 sec)

2. 數學函數

完整的內置數學函數見官方手冊

2.1 絕對值函數ABS(x)

mysql> select abs(0.9),abs(0),abs(-0.9);
+----------+--------+-----------+
| abs(0.9) | abs(0) | abs(-0.9) |
+----------+--------+-----------+
| 0.9      |      0 | 0.9       |
+----------+--------+-----------+
1 row in set

2.2 取模函數mod(x,y)

取x/y後的餘數。支持小數和負數。若是除數爲0或者除數被除數有一個爲null,則返回null。

mysql> select mod(31,8),mod(31.56,8),mod(-31.56,8),mod(31,0),mod(0,8);
+-----------+--------------+---------------+-----------+----------+
| mod(31,8) | mod(31.56,8) | mod(-31.56,8) | mod(31,0) | mod(0,8) |
+-----------+--------------+---------------+-----------+----------+
|         7 | 7.56         | -7.56         | NULL      |        0 |
+-----------+--------------+---------------+-----------+----------+
1 row in set

2.3 四捨五入函數round(x,y)

返回值x含有y位小數的四捨五入後的結果,若是省略y,則默認y爲0。

mysql> select round(3.15),round(3.15,1),round(-3.15),round(-3.15,1);
+-------------+---------------+--------------+----------------+
| round(3.15) | round(3.15,1) | round(-3.15) | round(-3.15,1) |
+-------------+---------------+--------------+----------------+
| 3           | 3.2           | -3           | -3.2           |
+-------------+---------------+--------------+----------------+
1 row in set

2.4 位數截斷函數truncate(x,y)

截斷x的小數位數使得最終保留y個小數位。它的用法和round(x,y)幾乎同樣,只不過truncate是用來截斷而不用來四捨五入。不能省略y但能夠等於0,且y不能爲負數。

mysql> select truncate(3.156,2),truncate(3.156,0);
+-------------------+-------------------+
| truncate(3.156,2) | truncate(3.156,0) |
+-------------------+-------------------+
| 3.15              | 3                 |
+-------------------+-------------------+
1 row in set

2.5 地板函數floor(x)和天花板函數ceiling(x)

地板函數返回比x小的最大整數,天花板函數返回比x大的最小整數。

mysql> select floor(3.4),floor(-3.4),ceiling(3.4),ceiling(-3.4);
+------------+-------------+--------------+---------------+
| floor(3.4) | floor(-3.4) | ceiling(3.4) | ceiling(-3.4) |
+------------+-------------+--------------+---------------+
|          3 |          -4 |            4 |            -3 |
+------------+-------------+--------------+---------------+
1 row in set

2.6 隨機函數rand()

每次隨機返回一個0-1之間不包括0和1的數,且每次運行結果都不一樣。

mysql> select rand(),rand();
+--------------------+----------------------+
| rand()             | rand()               |
+--------------------+----------------------+
| 0.7380041170287915 | 0.055543343588284534 |
+--------------------+----------------------+
1 row in set

若要取得0-100之間的數,可使用100去乘隨機值,但這樣得到的函數仍是不包含0和100這兩個邊界的。

mysql> select 100*rand(),100*rand(),100*rand();
+------------------+-------------------+--------------------+
| 100*rand()       | 100*rand()        | 100*rand()         |
+------------------+-------------------+--------------------+
| 22.5249471352668 | 96.80735235736458 | 16.461923454387044 |
+------------------+-------------------+--------------------+
1 row in set

若要取整,則能夠配合floor()或者ceiling()函數。但這樣取得的是[0,99]或者[1,100],而不能是[0,100]。

mysql> select floor(100*rand()) as '[0,99]',ceiling(100*rand()) as '[1,100]';
+--------+---------+
| [0,99] | [1,100] |
+--------+---------+
|     90 |      24 |
+--------+---------+
1 row in set

若是要想得到[0-100]這樣包含邊界的值,能夠拓寬隨機值。如下是兩種方法:

mysql> select ceiling(rand()*101-1),floor(rand()*101);
+-----------------------+-------------------+
| ceiling(rand()*101-1) | floor(rand()*101) |
+-----------------------+-------------------+
|                    92 |                55 |
+-----------------------+-------------------+
1 row in set

2.7 最值函數least(v1,v2,v3,…,vn)

從v1,v2,v3,…,vn中取出最小值。有如下幾種狀況:
(1)當只有數值類型時,取數值最小的。且負數有效。
(2)當只有字符串時,從第一個字符開始向後比較ascii碼,小寫字母小於大寫字母。
(3)數值和字符串比較,返回結果爲0。若要比較,須要先將數字轉換爲字符串格式,且字符串類型的數字老是小於字母。
(4)當n個成員之間存在null的時候,老是返回null,由於沒法比較。

mysql> select least(5,10,-1),least('ab','c','ac'),least('a',1),least('a','999'),least('a',1,null);
+----------------+----------------------+--------------+------------------+-------------------+
| least(5,10,-1) | least('ab','c','ac') | least('a',1) | least('a','999') | least('a',1,null) |
+----------------+----------------------+--------------+------------------+-------------------+
|             -1 | ab                   | 0            | 999              | NULL              |
+----------------+----------------------+--------------+------------------+-------------------+
1 row in set

2.8 最值函數greatest(v1,v2,v3,…,vn)

和least()函數相反,它取的是最大值。包括如下幾種狀況:
(1)當只有數值類型時,取最大值。負值有效。
(2)當只有字符串時,比較ascii碼,大寫字母大於小寫字母。
(3)當數字和字符串比較時,數字大於字符串,即返回數字中最大值。可是字符串類型的數字小於字母。這個least()不同。
(4)當存在null值時,返回null。

mysql> select greatest(5,10,-1) as A, greatest('ab','c','ac') as B, greatest('a',1) as C, greatest('a','999') as D, greatest('a',1,null) as E;
+----+---+---+---+------+
| A  | B | C | D | E    |
+----+---+---+---+------+
| 10 | c | 1 | a | NULL |
+----+---+---+---+------+
1 row in set, 2 warnings (0.00 sec)

3 日期時間函數

有不少不少,官方手冊:日期時間函數。如下挑幾個介紹。

3.1 當前日期時間

返回當前日期:curdate()、current_date(),它們是同義詞;
返回當前時間:curtime()、current_time(),它們是同義詞;
返回當前日期時間:now()、current_timestamp()、localtime()、localtimestamp、localtimestamp()、sysdate(),除了sysdate(),其他的都是now()的同義詞。

mysql> select curdate(),current_date(),current_timestamp(),curtime(),localtime(),now(),sysdate();

注意,now()和sysdate()是不一樣的。now()返回的是執行SQL語句那一刻的時間(若是now()是在存儲過程或函數或觸發器中,則now()返回的是這些程序開始調用執行的時刻),而sysdate()返回的是實時更新的當前時間,即操做系統當前的時間。經過下面的例子就知道了:

mysql> SELECT NOW(),CURRENT_TIMESTAMP(),SYSDATE(),LOCALTIME(),
       SLEEP(2),
       NOW(),CURRENT_TIMESTAMP(),SYSDATE(),LOCALTIME()\G
*************************** 1. row ***************************
              now(): 2017-03-24 13:30:09 current_timestamp(): 2017-03-24 13:30:09 sysdate(): 2017-03-24 13:30:09 localtime(): 2017-03-24 13:30:09 sleep(2): 0 now(): 2017-03-24 13:30:09 current_timestamp(): 2017-03-24 13:30:09 sysdate(): 2017-03-24 13:30:11 # 注意此處sleep 2秒後的時間 localtime(): 2017-03-24 13:30:09 1 row in set (2.00 sec)

能夠看到,sleep(2)後,sysdate()返回的比其餘的函數晚了兩秒,而其餘的函數返回的和sleep(2)以前的時間是同樣的,且都是開始執行語句的時間。

3.2 week(DATE)

返回給定日期在當年是第幾周。

mysql> select week(now());
+-------------+
| week(now()) |
+-------------+
|          12 |
+-------------+
1 row in set

3.3 year(DATE)、monthname(DATE)、day(DATE)、quarter(DATE)

返回所給日期的年份、月份、月中天(因此day()的同義詞是dayofmonth()函數)以及季度,不過返回的月份是英文全名。

mysql> select year(now()),monthname(now());
+-------------+------------------+
| year(now()) | monthname(now()) |
+-------------+------------------+
|        2017 | March            |
+-------------+------------------+
1 row in set

3.4 hour(TIME)、minute(TIME)、second(TIME)

返回給定時間值的小時、分鐘、秒部分。

mysql> select now(),hour(now()),minute(now()),second(now());
+---------------------+-------------+---------------+---------------+
| now()               | hour(now()) | minute(now()) | second(now()) |
+---------------------+-------------+---------------+---------------+
| 2017-03-23 14:21:57 |          14 |            21 |            57 |
+---------------------+-------------+---------------+---------------+
1 row in set

3.5 extract(part from DATE)

從給定的DATETIME中提取秒(second)、分(minute)、時(hour)、日(day)、月(month)、周(week)、年(year),還支持季度(quarter)提取。和SQL Server中的datepart()函數同樣的功能。

mysql> select extract(year from now()) as year_part, extract(month from now()) as month_part, extract(day from now()) as day_part, extract(week from now()) as week_part;
+-----------+------------+----------+-----------+
| year_part | month_part | day_part | week_part |
+-----------+------------+----------+-----------+
|      2017 |         10 |       18 |        42 |
+-----------+------------+----------+-----------+
1 row in set (0.00 sec) mysql> select now(),extract(hour from now()) as hour_part, extract(minute from now()) as minute_part, extract(second from now()) as second_part;
+---------------------+-----------+-------------+-------------+
| now()               | hour_part | minute_part | second_part |
+---------------------+-----------+-------------+-------------+
| 2017-10-18 04:34:12 |         4 |          34 |          12 |
+---------------------+-----------+-------------+-------------+
1 row in set (0.00 sec)

3.6 dayname(DATE)和dayofweek(DATE)

dayname返回給定日期是星期幾,返回的週日期name的都是英文全名。而dayofweek返回的是數字表明的星期幾,1表示週日,7表示週六。

mysql> select dayname(20131111),dayofweek('20131111');
+-------------------+-----------------------+
| dayname(20131111) | dayofweek('20131111') |
+-------------------+-----------------------+
| Monday            |                     2 |
+-------------------+-----------------------+
1 row in set (0.00 sec)

3.7 日期時間格式化

日期格式化:date_format(date,fmt)
時間格式化:time_format(time,fmt)

其中fmt爲日期時間的描述格式,使用%開頭進行描述,例如%Y表示4位數字的年份,%m表示2位數字的月份等,更多的格式見官方手冊fmt

mysql> select date_format('20131012','%Y-%m-%d');
+------------------------------------+
| date_format('20131012','%Y-%m-%d') |
+------------------------------------+
| 2013-10-12                         |
+------------------------------------+
1 row in set (0.00 sec)

3.8 日期時間計算

增長日期:DATE_ADD(date,interval expr unit),ADDDATE(date,interval expr unit),它們是同義詞;
減去日期:DATE_SUB(date,interval expr unit),SUBDATE(date,interval expr unit),它們是同義詞;

在給定日期date基礎上加或減去某種格式表達的日期時間。interval是關鍵字,expr是用來給定加減多少時間的表達式,unit是expr要表達的日期類型,見下圖。其中expr的描述方式和unit是對應的。

Unit Description
MICROSECOND Microseconds
SECOND Seconds
MINUTE Minutes
HOUR Hours
DAY Days
WEEK Weeks
MONTH Months
QUARTER Quarters
YEAR Years
SECOND_MICROSECOND Seconds.Microseconds
MINUTE_MICROSECOND Minutes.Seconds.Microseconds
MINUTE_SECOND Minutes.Seconds
HOUR_MICROSECOND Hours.Minutes.Seconds.Microseconds
HOUR_SECOND Hours.Minutes.Seconds
HOUR_MINUTE Hours.Minutes
DAY_MICROSECOND Days Hours.Minutes.Seconds.Microseconds
DAY_SECOND Days Hours.Minutes.Seconds
DAY_MINUTE Days Hours.Minutes
DAY_HOUR Days Hours
YEAR_MONTH Years-Months

例如year_month單元,從上表中得出它的格式是"years month"表示計算year部分和month部分的間隔。expr中year和month之間使用任意分隔符均可以,例如"1_2"、"1!2"、"1-2"和"1 2"都是容許的。若是使用day_minute單元,它的意義是"days hours.minutes",那麼expr中就須要給定3個值,這3個值從前向後分別表明日、時、分,中間能夠用任意分隔符分隔,例如'3-2-1'表示3天2小時1分鐘。

expr的前面能夠加上"+"和"-",分別表示加和減,不寫時默認爲"+",因此date_add和date_sub之間經過正負符號是能夠等價的。

如下是示例:

mysql> select now(), date_add(now(),interval 31 day) as add31days, date_add(now(),interval '1_2' year_month) as add1year2month;
+---------------------+---------------------+---------------------+
| now()               | add31days           | add1year2month      |
+---------------------+---------------------+---------------------+
| 2017-10-18 05:00:11 | 2017-11-18 05:00:11 | 2018-12-18 05:00:11 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

上述例子中使用了上面的第二列表示在當前日期內加上31天后的時間,第三列表示在當前日期基礎上加上1年又2個月以後的時間。

若是date_add中expr使用的是負數,則表示減。

mysql> select now(),
              date_add(now(),interval '-31' day) as jian31days,
              date_add(now(),interval '-1_2' year_month) as jian1year2month;
+---------------------+---------------------+---------------------+
| now()               | jian31days          | jian1year2month     |
+---------------------+---------------------+---------------------+
| 2017-10-18 05:00:58 | 2017-09-17 05:00:58 | 2016-08-18 05:00:58 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

上面第二列表示在當前日期上減去31天后的時間,第三列表示在當前日期基礎上減去1年又2個月以後的時間。

3.9 datediff(expr1,expr2)

expr1和expr2之間的天數差,是expr1減去expr2。

mysql> select now(),datediff(now(),'2018-01-01');
+---------------------+------------------------------+
| now()               | datediff(now(),'2018-01-01') |
+---------------------+------------------------------+
| 2017-03-23 14:57:06 |                         -284 |
+---------------------+------------------------------+
1 row in set

3.10 LAST_DAY(datetime)

返回給定日期所在月的最後一天。

mysql> select last_day(now()),last_day('2016-02-03');
+-----------------+------------------------+
| last_day(now()) | last_day('2016-02-03') |
+-----------------+------------------------+
| 2017-03-31      | 2016-02-29             |
+-----------------+------------------------+
1 row in set

4 流程控制之條件判斷函數

在MySQL/MariaDB中主要有if、ifnull和case語句進行條件判斷。其中if語句和SQL Server中的if相差較大。

4.1 if(expr,true_value,false_value)

if函數用來判斷expr是否爲真,若是爲真,則返回true_value,不然返回false_value。這和if語句是不同的。

mysql> select if(1>2,'a','b'),if(2>1,'a','b');
+-----------------+-----------------+
| if(1>2,'a','b') | if(2>1,'a','b') |
+-----------------+-----------------+
| b               | a               |
+-----------------+-----------------+
1 row in set

expr判斷是否爲真的依據是expr的結果非0且非null。因此也能夠直接使用數字表示真假,但不能使用字母表示真假。

mysql> select if(99,'a','b'),if(0,'a','b'),if(null,'a','b'),if('2','a','b'),if('c','a','b');
+----------------+---------------+------------------+-----------------+-----------------+
| if(99,'a','b') | if(0,'a','b') | if(null,'a','b') | if('2','a','b') | if('c','a','b') |
+----------------+---------------+------------------+-----------------+-----------------+
| a              | b             | b                | a               | b               |
+----------------+---------------+------------------+-----------------+-----------------+
1 row in set, 1 warning (0.00 sec)

4.2 ifnull(value1,value2)

若是value1不爲空則返回value1,不然返回value2。總之就是給定一個非null值。容許value2爲null。

mysql> select ifnull(1,'a'),ifnull('a','b'),ifnull(null,'a'),ifnull('a',null),ifnull(null,null);
+---------------+-----------------+------------------+------------------+-------------------+
| ifnull(1,'a') | ifnull('a','b') | ifnull(null,'a') | ifnull('a',null) | ifnull(null,null) |
+---------------+-----------------+------------------+------------------+-------------------+
| 1             | a               | a                | a                | NULL              |
+---------------+-----------------+------------------+------------------+-------------------+
1 row in set

MySQL中的ifnull函數基本等價於SQL Server中的isnull()函數,跟SQL Server中的nullif函數相差很是大。且MySQL中的ifnull只能從兩個參數中取一個非空值,而SQL Server中的coalesce()函數能夠從多個參數中選第一個非空值。

4.3 nullif(expr1,expr2)

若是expr1等於expr2,則返回null,不然返回expr1。也就是說,二者不相等時取前者,不然取NULL。若是expr1和expr2任意一個爲null,則直接返回null。這等價於:

case when expr1 = expr2 || expr1 is null || expr2 is null then null 
else expr1
end

例如:

mysql> select nullif(1,1),nullif(1,2),nullif(null,1);   
+-------------+-------------+----------------+
| nullif(1,1) | nullif(1,2) | nullif(null,1) |
+-------------+-------------+----------------+
|        NULL |           1 | NULL           |
+-------------+-------------+----------------+
1 row in set (0.00 sec)

4.4 case語句

和SQL Server中的case語法差很少。也是兩種格式:case when ...then...else...endcase ...when...then...else...end

-- 格式一:
CASE WHEN express_1 THEN value_1 
     WHEN express_2 THEN value_2 
    … 

ELSE value_n   
END;
-- 格式二:
CASE express WHEN value1 THEN value_1 
             WHEN value2 THEN value_2 
             ... 
ELSE value_n   
END;

注意,若是採用CASE...WHEN的寫法格式,則express只能與value進行等同性檢查。例如:

/*格式一示例*/
SELECT StudentID, CASE WHEN Mark < 60 THEN '不及格' WHEN Mark >= 60 AND Mark < 70 THEN '及格' WHEN Mark >= 70 AND Mark < 80 THEN '良好' ELSE '優秀' END FROM Tscore;

/*格式二示例*/
SELECT StudentID , CASE FLOOR(Mark / 10) WHEN 5 THEN '不及格' WHEN 6 THEN '及格' WHEN 7 THEN '良好' ELSE '優秀' END FROM Tscore;

其中格式二爲case ... when的格式,它的when部分的值都只能和floor(mark/10)作等於號比較,這是等同性檢查。而格式一的寫法就靈活的多,既能夠作等號比較,也能作大於號或其餘方式的比較。

5 類型轉換函數cast()和convert()

類型轉換函數用來轉換數據類型。在MySQL/MariaDB中能夠轉換的類型有如下幾種:

二進制: BINARY[(N)] 
字符型: CHAR[(N)] 
日期 : DATE 
時間: TIME 
日期時間型 : DATETIME
浮點數 : DECIMAL 
整數 : SIGNED 
無符號整數 : UNSIGNED

其中convert()有兩種語法:

CONVERT(expr,type), CONVERT(expr USING transcoding_name)

後者用於不一樣字符集之間轉換數據。

在轉換數據類型時,cast和convert的功能基本是同樣的,只是寫法不一樣。

mysql> SELECT CAST('3.35' AS signed);
+------------------------+
| CAST('3.35' AS signed) |
+------------------------+
|                      3 |
+------------------------+
1 row in set

mysql> SELECT CAST(100 AS CHAR(2)),CONVERT('2013-8-9 12:12:12',TIME);
+----------------------+-----------------------------------+
| CAST(100 AS CHAR(2)) | CONVERT('2013-8-9 12:12:12',TIME) | +----------------------+-----------------------------------+ | 10 | 12:12:12 | +----------------------+-----------------------------------+ 1 row in set

帶有using的convert函數用來轉換字符集。

mysql> SELECT CHARSET('string'),CHARSET(CONVERT('string' USING latin1));
+-------------------+-----------------------------------------+
| CHARSET('string') | CHARSET(CONVERT('string' USING latin1)) |
+-------------------+-----------------------------------------+
| utf8mb4           | latin1                                  |
+-------------------+-----------------------------------------+
1 row in set

6 其它實用函數

  • (1). sleep(N)
    延遲N秒後執行後面的語句。特殊點在於sleep()函數能夠用於select的選擇列表。
    select a,sleep(2),a from t;
    注意上面的語句中,是先查詢a,再阻塞2秒,以後再查詢a,而不是先阻塞後再查詢兩次a或查詢兩次a後再阻塞。也就是說,對於mysql/mariadb來講,select的選擇列表之間是有前後順序的,不像sql server,選擇列之間是徹底平行等價的。能夠經過下面的例子來驗證:
    select sysdate(),sleep(1),sysdate();
  • (2). 返回當前數據庫名database()
  • (3). 返回當前數據庫版本version()
  • (4). 返回當前登陸用戶名user()

    mysql> select database(),version(),user();
    +------------+-----------+--------------------+
    | database() | version() | user()             |
    +------------+-----------+--------------------+
    | test       | 5.6.35    | root@192.168.100.1 |
    +------------+-----------+--------------------+
    1 row in set
  • (5). 返回加密字符串password(str)

  • (6). 返回字符串的MD5值md5(str)

    mysql> select password('abc'),md5('abc');
    +-------------------------------------------+----------------------------------+
    | password('abc')                           | md5('abc')                       |
    +-------------------------------------------+----------------------------------+
    | *0D3CED9BEC10A777AEC23CCC353A8C08A633045E | 900150983cd24fb0d6963f7d28e17f72 |
    +-------------------------------------------+----------------------------------+
    1 row in set
  • (7). last_insert_id()函數
    LAST_INSERT_ID()返回最後一個INSERT或UPDATE爲AUTO_INCREMENT列設置的第一個發生的值。該函數值不是基於表的,這一點和SQL Server是不一樣的,也就是說,對a表插入的最後一個值是10,再對b表插入的最後一個值是15,那麼函數返回的將是15。而且last_insert_id的值和一次插入一條記錄仍是一次批量插入的方式有關。

    mysql> create table test10(id int primary key auto_increment,name char(20));
    # 一次插入一條記錄。
    mysql> insert into test10 values(null,'gaoxiaofang');
    mysql> insert into test10 values(null,'malongshuai');
    mysql> insert into test10 values(null,'longshuai');
    mysql> insert into test10 values(null,'xiaofang');
    mysql> select * from test10;
    +----+-------------+
    | id | name        |
    +----+-------------+
    |  1 | gaoxiaofang |
    |  2 | malongshuai |
    |  3 | longshuai   |
    |  4 | xiaofang    |
    +----+-------------+
    4 rows in set

    查看last_insert_id的值,結果將是4。

    mysql> select last_insert_id();
    +------------------+
    | last_insert_id() |
    +------------------+
    |                4 |
    +------------------+
    1 row in set

    一次插入多條記錄,並查看last_insert_id()的值。

    mysql> insert into test10 values(null,'tun\'er'),(null,'woniu'),(null,'wugui'); mysql> select *,last_insert_id() from test10; +----+-------------+------------------+ | id | name | last_insert_id() | +----+-------------+------------------+ | 1 | gaoxiaofang | 5 | | 2 | malongshuai | 5 | | 3 | longshuai | 5 | | 4 | xiaofang | 5 | | 5 | tun'er      |                5 |
    |  6 | woniu       |                5 |
    |  7 | wugui       |                5 |
    +----+-------------+------------------+
    7 rows in set

    能夠發現這裏last_insert_id的值不是7而是5,這是由於批量插入的時候last_insert_id的值將會是批量中的第一條記錄的自增列值。 且last_insert_id的值和表是無關的,只和會話環境有關。例如再向另一個表插入後,last_insert_id的值將變爲另外一個值。

    mysql> create table test11(id int primary key auto_increment,name char(20));
    mysql> insert into test11 values(null,'gaoxiaofang');
    mysql> insert into test11 values(null,'malongshuai');
    mysql> insert into test11 values(null,'longshuai');
    mysql> insert into test11 values(null,'xiaofang');
    mysql> select last_insert_id();
    +------------------+
    | last_insert_id() |
    +------------------+
    |                4 |
    +------------------+
    1 row in set

    能夠發現它又變回了4。

更多關於auto_increment計算相關內容見Mysql/MariaDB自增列

相關文章
相關標籤/搜索