1. 程式人生 > 其它 >MySQL常用函式(瞭解)

MySQL常用函式(瞭解)

MySQL支援的字串函式

函式 功能
concat(s1,s2,......sn) 連線s1,s2,.....,sn為一個字串
insert(str,x,y,instr) 將字串str從第x位置開始,y個字元長的子串替換為字串instr,若 x 超過字串長度,則返回值為原始字串。假如 y的長度大於其他字串的長度,則從位置 x 開始替換。若任何一個引數為 NULL,則返回值為 NULL。
lower(str) 將字串str中字元變為小寫
upper(str) 將字串str中字元變為大寫
left(str,x) 返回字串str最左邊的x個字元
right(str,x)
返回字串str最右邊的x個字元
lpad(str,n,pad) 用字串pad對str最左邊進行填充,直到長度為n個字元長度
rpad(str,n,pad) 用字串pad對str最右邊進行填充,直到長度為n個字元長度
ltrim(str) 去掉字串str左側的空格
rtrim(str) 去掉字串str右側的空格
repeat(str,x) 返回str重複x次的結果
replace(str,a,b) 用字串b替換字串str中所有出現的字串a
strcmp(s1,s2) 比較字串s1和s2
trim(str) 去掉字串行尾和行頭的空格
substring(str,x,y)
返回從字串str x位置起y個字元長度的字串
select left('abcd',2); -- ab
select concat('ab','cd','wz'); -- abcdwz
select insert('abcde',2,3,null); -- null
select INSERT('abcde',2,2,'yyyyy'); -- ayyyyyde
select lpad('ab',4,'mkb'); -- mkab
select replace('abc','a','m'); -- mbc
select strcmp('ab','ac'); -- -1
select strcmp('
ba','ac'); -- 1 select substring('abc',1,2); -- ab select LOWER('ABCd'); -- abcd select trim(' dad '); -- dad

MySQL支援的數值函式

函式 功能
abs(x) 返回x的絕對值
ceil(x) 返回大於x的最小整數值
floor(x) 返回小於x的最大整數值
mod(x,y) 返回x/y的模
rand() 返回0~1內的隨機值
round(x,y) 返回引數x的四捨五入的有y位小數的值
truncate(x,y) 返回數字x截斷為y位小數的結果
select abs(-1); -- 1
select ceil(2.1); -- 3
select floor(2.9); -- 2
select mod(7,5); -- 2
select rand(); -- 隨機的 0.3777260141239744
select round(5.555,2);-- 5.56
select TRUNCATE(15.26,1); -- 15.2

MySQL支援的日期和時間函式

函式 功能
curdate() 返回當前日期
curtime() 返回當前時間
now() 返回當前的日期和時間
unix_timestamp(date) 返回日期date的unix時間戳
from_unixtime 返回unix時間戳的日期值
week(date) 返回日期date為一年中的第幾周
year(date) 返回日期date的年份
hour(time) 返回time的小時值
minute(time) 返回time的分鐘值
monthname(date) 返回日期date的月份名
date_format(date,fmt) 返回按字串fmt格式化日期date值
date_add(date,interval expr type) 返回一個日期或時間值加上一個時間間隔的時間值
datediff(expr,expr2) 返回起始時間expr和結束時間expr2之間的天數

MySQL支援的日期和時間格式

格式符 格式說明
%S和%s 兩位數字形式的秒(00,01,...,59)
%i 兩位數字形式的分(00,01,...,59)
%H 兩位數字形式的小時,24小時(00,01,...,23)
%h和%I 兩位數字形式的小時,12小時(00,01,...,11)
%k 數字形式的小時,24小時(0,1,...,23)
%l 數字形式的小時,12小時(0,1,...,12)
%T 24小時的時間形式(hh:mm:ss)
%r 12小時的時間形式(hh:mm:ssAM或hh:mm:ssPM)
%p AM或PM
%W 一週中每一天的名稱(Sunday,Monday,...,Saturday)
%a 一週中每一天名稱的縮寫(Sun,Mon,...,Sat)
%d 兩位數字表示月中的天數(00,01,...,31)
%e 數字形式表示月中的天數(00,01,...,31)
%D 英文字尾表示月中的天數(1st,2nd,3rd,...)
%w 以數字形式表示週中的天數(0=Sunday,1=Monday,...,6=Saturday)
%j 以3位數字表示年中的天數(001,002,...,366)
%U 周(0,1,52),其中Sunday為週中的第一天
%u 周(0,1,52),其中Monday為週中的第一天
%M 月名(January,February,...,December)
%b 縮寫的月名
%m 兩位數字表示的月份(01,02,...,12)
%c 數字表示的月份(1,2,...,12)
%Y 4位數字表示的年份
%y 兩位數字表示的年份
%% 直接值“%”

MySQL支援的日期間隔型別

表示式型別 描述 格式
hour 小時 hh
minute mm
second ss
year YY
month MM
day DD
year_month 年和月 YY-MM
day_hour 日和小時 DD hh
day_minute 日和分鐘 DD hh:mm
day_second 日和秒 DD hh:mm:ss
hour_minute 小時和分 hh:mm
hour_second 小時和秒 hh:ss
minute_second 分鐘和秒 mm:ss

MySQL支援的流程函式

函式 功能
if(value,t,f) 如果value是真,返回t;否則返回f
ifnull(value1,value2) 如果value1不為空,返回value1,否則value2
case when[value1] then [result]...else [default] end 如果value1是真,返回result,否則返回default
case [expr] when [value1] then [result1] ... else [default] end 如果expr等於value1,返回result1,否則返回default
select 
CASE 
    WHEN 2>3 THEN 'a'
    ELSE    'b'
end;
-- b
select 
case 'a'
    when 'a'    then '1'
    ELSE '2'
END;
-- 1

MySQL的JSON函式

1、建立JSON函式

函式 功能
json_array() 建立json陣列
json_object() 建立json物件
json_quote()/json_unquote() 加上/去掉json文件兩邊的雙引號

2、查詢JSON函式

函式 功能
json_contains() 查詢文件中是否包含指定的元素
json_contains_path() 查詢文件中是否包含指定的路徑
json_extract() 根據條件提取文件中的資料
json_keys() 提取所有key的集合
json_search() 返回所有符合條件的路徑集合

3、修改JSON函式

函式 功能
json_merge()(deprecated 5.7.22) json_merge_preserve 將兩個文件合併
json_array_append() 陣列尾部追加元素
json_array_insert() 在陣列的指定位置插入元素
json_remove() 刪除文件中指定位置的元素
json_replace() 替換文件中指定位置的元素
json_set() 給文件中指定位置的元素設定新值,如果元素不存在,則進行插入

4、查詢JSON元資料的函式

函式 功能
json_depth() JSON文件的深度(元素最大巢狀層數)
json_length() JSON文件的長度(元素個數)
json_type() JSON文件型別(陣列、物件、標量型別)
json_valid() JSON格式是否合法

5、JSON工具函式

函式 功能
json_pretty() 美化JSON格式
json_storage_size() JSON文件佔用的儲存空間
json_storage_free() JSON文件更新操作後剩餘的空間,MySQL8.0新增
json_table() 將JSON文件轉換為表格,MySQL8.0新增
json_arrayagg() 將聚合後引數中的多個值轉換為JSON陣列
json_objectagg() 將兩個列或者是表示式解釋為一個key和一個value,返回一個JSON物件

MySQL視窗函式

1、ROW_NUMBER() 排序返回序號(連續的,指定排序欄位值相等也會出現不同序號)

row_number()後面的over是關鍵字,用來指定函式執行的視窗範圍,如果後面什麼都不寫,則意味著視窗包含所有行,視窗:函式在所有行上進行計算;如果不為空,則支援以下4種語法:

window_name:給視窗指定一個別名,如果SQL中涉及的視窗較多,採用別名則更清晰易讀;

partition by子句:視窗按照哪些欄位進行分組,視窗函式在不同的分組上分別執行;

order by子句:按照哪些欄位進行排序,視窗函式將按照排序後的記錄順序進行編號,既可以和partition子句配合使用,也可以單獨使用;

frame子句:frame是當前分割槽的一個子集,子句用來定義子集的規則,通常用來作為滑動視窗使用。

基於行

基於範圍

例如:  select 要查詢的值,row_number() over(order by 表中某一個列名稱) as 起一個列名 from 表名稱

2、RANK()/DENSE_RANK()

RANK()/DENSE_RANK():

rank()/dense_rank()這兩個函式與row_number()非常類似,只是在出現重複值時處理邏輯有所不同。

rank():不一定連續的,指定排序欄位值相等,序號相同,但是下一個序號就會跳躍

dense_rank():連續的,指定排序欄位值相等,序號相同,但是下一個序號不會就跳躍

select *,row_number() over(PARTITION by sex order by age asc) row_num from student;
​
select *,rank() over(PARTITION by sex order by age asc) row_num from student;
​
select *,dense_rank() over(PARTITION by sex order by age asc) row_num from student;

3、PERCENT_RANK()/CUME_DIST()

percent_rank()和cume_dist()這兩個函式都是計算資料分佈的函式,percent_rank()和之前的rank()函式相關,每行按照以下公式進行計算:

(rank-1)/(rows-1),其中,rank為rank()函式產生的序號,rows為當前視窗的記錄總行數。

相比percent_rank(),cume_dist()函式的應用場景更多,它的作用是分組內小於等於rank值的行數/分組內的總行數(統計大於等於當前訂單金額的訂單數,佔總訂單數的比例)。

4、NTILE(N)

ntile()函式的功能是對一個數據分割槽中的有序結果集進行劃分,將其分為N個組,併為每個小組分配一個唯一的組編號。

此函式在資料分析中應用較多,比如由於資料最大,需要將資料分配到N個並行的程序分別計算,此時就可以用NTILE(N)對資料進行分組,由於記錄數不一定被N整除,所以每組記錄數不一定完全一致,然後將不同組號的資料再分配。

5、NTH_VALUE(expr,N)

NTH_VALUE(expr,N)函式可以返回視窗中第N個expr的值,expr既可以是表示式,也可以是列名。

6、LAG(expr,N)/LEAD(expr,N)

LAG(expr,N)和LEAD(expr,N)這兩個函式的功能是獲取當前資料行按照某種排序規則上的N行(LAG)/下N行(LEAD)資料的某個欄位。

7、FIRST_VALUE(expr)/LAST_VALUE(expr)

FIRST_VALUE(expr)和LAST_VALUE(expr)這兩個函式的功能分別是獲得滑動視窗範圍內引數欄位中第一個和最後一個的值。

8、聚合函式作為視窗函式

使用各種聚合函式(sum、avg、max、min、count)作為視窗函式來使用

MySQL中的其他常用函式

函式 功能
DATABASE() 返回當前資料庫名
VERSION() 返回當前資料庫版本
USER() 返回當前登入使用者名稱
INET_ATON(IP) 返回IP地址的數字表示
INET_NTOA(num) 返回數字代表的IP地址
PASSWORD(str) 返回字串str的加密版本
MD5() 返回字串str的MD5值

加密與解密函式

  PASSWORD(str) -- 返回字串str的加密版本,41位長的字串。加密結果`不可逆`,MySQL8.0已棄用
  MD5(str) -- 返回字串str的md5加密後的值若引數為NULL,則會返回NULL
  SHA(str) -- 從原明文密碼str計算並返回加密後的密碼字串,當引數為NULL時,返回NULL
  ENCODE(value,password_seed) -- 返回使用password_seed作為加密密碼加密value,MySQL8.0已棄用
  DECODE(value,password_seed) -- 返回使用password_seed作為加密密碼解密value,MySQL8.0已棄用

example:

  -- PASSWORD在MySQL8.0棄用
  SELECT PASSWORD('mysql') FROM DUAL;
  -- MD5()、SHA()加密不可逆
  SELECT MD5('mysql'),SHA('mysql') FROM DUAL;
  -- ENCODE、DECODE()在MySQL8.0棄用
  SELECT ENCODE('sakura','kinomoto'),DECODE(ENCODE('sakura','kinomoto'),'kinomoto') FROM DUAL;

MySQL資訊函式

  VERSION() -- 返回當前MySQL的版本號
  CONNECTION_ID() -- 返回當前MySQL伺服器的連線數
  DATABASE(),SCHEMA() -- 返回MySQL命令行當前所在的資料庫
  USER() -- 返回當前連線MySQL的使用者名稱,返回結果格式為“主機名@使用者名稱”
  CURRENT_USER() -- 返回當前連線MySQL的使用者名稱,返回結果格式為“主機名@使用者名稱”
  SYSTEM_USER() -- 返回當前連線MySQL的使用者名稱,返回結果格式為“主機名@使用者名稱”
  SESSION_USER() -- 返回當前連線MySQL的使用者名稱,返回結果格式為“主機名@使用者名稱”
  CHARSET(value) -- 返回字串value自變數的字符集
  COLLATION(value) -- 返回字串value的比較規則

example:

  SELECT VERSION() FROM DUAL;
  SELECT CONNECTION_ID() FROM DUAL;
  SELECT DATABASE(),SCHEMA() FROM DUAL;
  SELECT USER(),CURRENT_USER(),SYSTEM_USER(),SESSION_USER() FROM DUAL;
  SELECT CHARSET('sakura') FROM DUAL;
  SELECT COLLATION('sakura') FROM DUAL;

聚合函式是對一組資料進行彙總的函式,輸入的是一組資料的集合,輸出的是單個值。聚合函式不能巢狀呼叫。

常見的聚合函式型別

  AVG() -- 平均數函式
  SUM() -- 求和函式
  MAX() -- 最大值函式
  MIN() -- 最小值函式
  COUNT() -- 求總數函式
  • AVG() 和 SUM() 只適用於數值型別的欄位
  • MAX() 和 MIN() 適用於數值型別、字串型別、時間型別
  • COUNT(*)、COUNT(1)返回表中記錄總數,適用於任意資料型別
  • COUNT(expr) 返回expr不為空的記錄總數
  • AVG() = SUM()/COUNT()
  • 聚合函式忽略NULL
  -- AVG()、SUM()只適用於資料型別
  SELECT AVG(salary),SUM(salary) FROM employees;
   
  -- MAX()、MIN()適用於數值型別、字串型別、時間型別
  SELECT MAX(salary),MIN(salary) FROM employees;
  SELECT MAX(last_name),MIN(last_name) FROM employees;
  SELECT MAX(hire_date),MIN(hire_date) FROM employees;
   
  SELECT COUNT(employee_id) FROM employees;
  SELECT COUNT(commission_pct) FROM employees;
  SELECT COUNT(*) FROM employees;
  SELECT COUNT(1) FROM employees;
   
  SELECT AVG(salary),SUM(salary)/COUNT(salary) FROM employees;
  SELECT AVG(commission_pct),SUM(commission_pct)/COUNT(commission_pct),SUM(commission_pct)/COUNT(*) FROM employees;

使用 COUNT(*)、COUNT(1)、COUNT(具體欄位) 統計表中的記錄數,哪個效率更高?

  • 如果使用的是MyISAM儲存引擎,則三者效率相同,都是O(1);
  • 如果使用是InnoDB儲存引擎,則三者效率:COUNT(*) = COUNT(1) > COUNT(具體欄位)

GROUP BY的使用

  SELECT 欄位名1, 分組函式(欄位名2)
  FROM 表名
  GROUP BY 欄位名1;
  • 可以使用GROUP BY子句將表中的資料分成若干組;
  • 在SELECT列表中所有未包含在組函式中的列都應該包含在 GROUP BY子句中,反之,GROUP BY中宣告的欄位可以不出現在SELECT中;
  • GROUP BY 宣告在 FROM 後面,WHERE 後面,ORDER BY 前面,LIMIT 前面
  • 使用 WITH ROLLUP 關鍵字之後,在所有查詢出的分組記錄之後增加一條記錄,該記錄計算查詢出的所有記錄的總和,即統計記錄數量。
  • 當使用 ROLLUP 時,不能同時使用 ORDER BY 子句進行結果排序,即 ROLLUP 和 ORDER BY 是互相排斥的。
  -- SELECT 中出現的非分組函式的欄位必須宣告在 GROUP BY 中。
  -- GROUP BY 中宣告的欄位可以不出現在SELECT中
  SELECT department_id,AVG(salary),SUM(salary),MAX(salary) FROM employees GROUP BY department_id;
  SELECT department_id,job_id,AVG(salary),SUM(salary) FROM employees GROUP BY department_id,job_id;
  SELECT job_id,department_id,AVG(salary),SUM(salary) FROM employees GROUP BY job_id,department_id;
   
  SELECT department_id,AVG(salary) FROM employees GROUP BY department_id WITH ROLLUP;

HAVING的使用

  SELECT 欄位名1, 分組函式1(欄位名2)
  FROM 表名
  GROUP BY 欄位名1;
  HAVING 帶分組函式的過濾條件;
  • HAVING 必須宣告在 GROUP BY 後面。
  • 如果過濾條件中使用了聚合函式,則必須使用 HAVING 來替換 WHERE。否則,報錯。
  • 當過濾條件沒有聚合函式時,則此過濾條件中宣告在 WHERE 中或 HAVING 中都可以,建議宣告在 WHERE 中。
  • 開發中,我們使用 HAVING 的前提是 SQL 中使用了 GROUP BY。
  SELECT department_id,MAX(salary)
  FROM employees
  GROUP BY department_id
  HAVING MAX(salary) > 10000;
   
  SELECT department_id,MAX(salary)
  FROM employees
  WHERE department_id IN (10,20,30)
  GROUP BY department_id
  HAVING MAX(salary) > 10000;