本文目錄:
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
完整的內置字符串函數見官方手冊。css
有兩個字符串鏈接函數: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
分別是變小寫、變大寫、從左取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
有兩種: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
分別用來消除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
將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
使用字符串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
將string從位置p1開始,len個長度的字符替換爲instead_string。
mysql> select insert('woshimalongshuai',6,2,'gao');
+--------------------------------------+
| insert('woshimalongshuai',6,2,'gao') |
+--------------------------------------+
| woshigaolongshuai |
+--------------------------------------+
1 row in set
返回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)
比較string1和string2的ascii碼大小,從前向後依次比較。strcmp認爲大小寫字母是等價的,因此它們相等。且存在null時,直接返回null。
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()也能實現,這兩個函數更多的用於取最值,特別是用於數值比較,因此在後文解釋。
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中:
這三個函數的做用相同,都是返回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
返回子串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
返回字符串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)
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
反轉字符串str的字符順序。
mysql> select reverse('hello');
+------------------+
| reverse('hello') |
+------------------+
| olleh |
+------------------+
1 row in set (0.00 sec)
完整的內置數學函數見官方手冊。
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
取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
返回值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
截斷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
地板函數返回比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
每次隨機返回一個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
從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
和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)
有不少不少,官方手冊:日期時間函數。如下挑幾個介紹。
返回當前日期: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)以前的時間是同樣的,且都是開始執行語句的時間。
返回給定日期在當年是第幾周。
mysql> select week(now());
+-------------+
| week(now()) |
+-------------+
| 12 |
+-------------+
1 row in set
返回所給日期的年份、月份、月中天(因此day()的同義詞是dayofmonth()函數)以及季度,不過返回的月份是英文全名。
mysql> select year(now()),monthname(now());
+-------------+------------------+
| year(now()) | monthname(now()) |
+-------------+------------------+
| 2017 | March |
+-------------+------------------+
1 row in set
返回給定時間值的小時、分鐘、秒部分。
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
從給定的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)
dayname返回給定日期是星期幾,返回的週日期name的都是英文全名。而dayofweek返回的是數字表明的星期幾,1表示週日,7表示週六。
mysql> select dayname(20131111),dayofweek('20131111');
+-------------------+-----------------------+
| dayname(20131111) | dayofweek('20131111') |
+-------------------+-----------------------+
| Monday | 2 |
+-------------------+-----------------------+
1 row in set (0.00 sec)
日期格式化: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)
增長日期: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個月以後的時間。
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
返回給定日期所在月的最後一天。
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
在MySQL/MariaDB中主要有if、ifnull和case語句進行條件判斷。其中if語句和SQL Server中的if相差較大。
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)
若是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()函數能夠從多個參數中選第一個非空值。
若是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)
和SQL Server中的case語法差很少。也是兩種格式:case when ...then...else...end
和case ...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)作等於號比較,這是等同性檢查。而格式一的寫法就靈活的多,既能夠作等號比較,也能作大於號或其餘方式的比較。
類型轉換函數用來轉換數據類型。在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
select a,sleep(2),a from t;
注意上面的語句中,是先查詢a,再阻塞2秒,以後再查詢a,而不是先阻塞後再查詢兩次a或查詢兩次a後再阻塞。也就是說,對於mysql/mariadb來講,select的選擇列表之間是有前後順序的,不像sql server,選擇列之間是徹底平行等價的。能夠經過下面的例子來驗證: select sysdate(),sleep(1),sysdate();
(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自增列。