【MySQL】函数
?
?
活動地址:CSDN21天學習挑戰賽
作者簡介:大家好我是狂暴于濤俠本俠
🦸個人主頁:狂暴于濤俠
MySQL的函數
- 🍛MySQL函數的概述
- 🥂1. 聚合函數
- 🥂2. 數學函數
- 🥂3. 字符串函數
- 🥂4. 日期函數
- 🥂5. 控制流函數
- 🥂6. 窗口函數
- 🌭序號函數
- 🌭開窗聚合函數- SUM,AVG,MIN,MAX
- 🌭分布函數- CUME_DIST和PERCENT_RANK
- 🌭前后函數- LAG和LEAD
- 🌭頭尾函數- FIRST_VALUE和LAST_VALUE
- 🌭其他函數-- NTH_VALUE(expr, n)、NTILE(n)
🍛MySQL函數的概述
概述:
在MySQL中,為了提高代碼重用性和隱藏實現細節,MySQL提供了很多函數。函數可以理解為別人封裝好的模板代碼。
- 在MySQL中,函數非常多,主要可以分為以下幾類:
- 1. 聚合函數
- 2. 數學函數
- 3. 字符串函數
- 4. 日期函數
- 5. 控制流函數
- 6. 窗口函數
🥂1. 聚合函數
概述:
語法:
group_concat([distinct] 字段名 [order by 排序字段 asc/desc] [separator ‘分隔符’])
說明:
(1)使用distinct可以排除重復值;
(2)如果需要對結果中的值進行排序,可以使用order by子句;
(3)separator是一個字符串值,默認為逗號。
首先我們先創建一個表格
create database mydb4; use mydb4;create table emp(emp_id int primary key auto_increment comment '編號',emp_name char(20) not null default '' comment '姓名',salary decimal(10,2) not null default 0 comment '工資',department char(20) not null default '' comment '部門' );insert into emp(emp_name,salary,department) values('張晶晶',5000,'財務部'),('王飛飛',5800,'財務部'),('趙剛',6200,'財務部'),('劉小貝',5700,'人事部'), ('王大鵬',6700,'人事部'),('張小斐',5200,'人事部'),('劉云云',7500,'銷售部'),('劉云鵬',7200,'銷售部'), ('劉云鵬',7800,'銷售部');
接下來進行一些操作:
-- 指定分隔符合并 select group_concat(emp_name separator ';' ) from emp;
-- 指定排序方式和分隔符 select department,group_concat(emp_name separator ';' ) from emp group by department;
-- 指定排序方式和分隔符 select department,group_concat(emp_name order by salary desc separator ';' ) from emp group by department;
🥂2. 數學函數
例子:
🥂3. 字符串函數
例子:
🥂4. 日期函數
🥂5. 控制流函數
-- 控制流函數 -- IF select if(5>3,'大于','小于'); select *,if(score >= 85, '優秀','及格') flag from score;
下面是if語句:
下面是case語句:
create table orders( oid int primary key, -- 訂單id price double, -- 訂單價格 payType int -- 支付類型(1:微信支付2:支付寶支付3:銀行卡支付4:其他) ); insert into orders values(1,1200,1); insert into orders values(2,1000,2); insert into orders values(3,200,3); insert into orders values(4,3000,1); insert into orders values( 5,1500,2);-- 方式1 select*, case payTypewhen 1 then '微信支付'when 2 then '支付寶支付'when 3 then '銀行卡支付'else'其他支付方式' end as payTypeStr from orders;-- 方式2 select *, case when payType=1 then '微信支付' when payType=2 then '支付寶支付' when payType=3 then '銀行卡支付' else '其他支付方式' end as payTypeStr from orders; select -- 輸出你好 2>1 對之后不會執行下面的 casewhen 2>1 then '你好'when 2<1 then 'hello'when 3>2 then '正確'else'其他' end as info ;🥂6. 窗口函數
介紹:
MySQL 8.0 新增窗口函數,窗口函數又被稱為開窗函數,與Oracle 窗口函數類似,屬于MySQL的一大特點.
非聚合窗口函數是相對于聚函數來說的。聚合函數是對一組數據計算后返回單個值(即分組),非聚合函數一次只會處理一行數據。窗口聚合函數在行記錄上計算某個字段的結果時,可將窗口范圍內的數據輸入到聚合函數中,并不改變行數。
語法結構:
window_function ( expr ) OVER (
PARTITION BY …
ORDER BY …
frame_clause
)
其中,window_function 是窗口函數的名稱;expr 是參數,有些函數不需要參數;OVER子句包含三個選項:
分區(PARTITION BY)
PARTITION BY選項用于將數據行拆分成多個分區(組),它的作用類似于GROUP BY分組。如果省略了 PARTITION BY,所有的數據作為一個組進行計算
排序(ORDER BY)
OVER 子句中的ORDER BY選項用于指定分區內的排序方式,與 ORDER BY 子句的作用類似
以及窗口大小(frame_clause)。
frame_clause選項用于在當前分區內指定一個計算窗口,也就是一個與當前行相關的數據子集。
🌭序號函數
序號函數有三個:ROW_NUMBER()、RANK()、DENSE_RANK(),可以用來實現分組排序,并添加序號。
格式:
row_number()|rank()|dense_rank() over (
partition by … - -按照什么分組
order by … - -每組按照什么排序
)
我們先創建一個表:
use mydb4; create table employee( dname varchar(20), -- 部門名 eid varchar(20), ename varchar(20), hiredate date, -- 入職日期 salary double -- 薪資 ); insert into employee values('研發部','1001','劉備','2021-11-01',3000); insert into employee values('研發部','1002','關羽','2021-11-02',5000); insert into employee values('研發部','1003','張飛','2021-11-03',7000); insert into employee values('研發部','1004','趙云','2021-11-04',7000); insert into employee values('研發部','1005','馬超','2021-11-05',4000); insert into employee values('研發部','1006','黃忠','2021-11-06',4000);insert into employee values('銷售部','1007','曹操','2021-11-01',2000); insert into employee values('銷售部','1008','許褚','2021-11-02',3000); insert into employee values('銷售部','1009','典韋','2021-11-03',5000); insert into employee values('銷售部','1010','張遼','2021-11-04',6000); insert into employee values('銷售部','1011','徐晃','2021-11-05',9000); insert into employee values('銷售部','1012','曹洪','2021-11-06',6000); -- 對每個部門的員工按照薪資排序,并給出排名 rn1 -- 對每個部門的員工按照薪資排序,并給出排名 rank rn2 -- 對每個部門的員工按照薪資排序,并給出排名 dense-rank rn3 select dname, ename, salary, row_number() over(partition by dname order by salary desc) as rn1,-- 就算salary一樣還是分出第一第二 rank() over(partition by dname order by salary desc) as rn2,-- 就算salary一樣不分出第一第二但是沒有第二而是直接第三 dense_rank() over(partition by dname order by salary desc) as rn3-- salary一樣并列第一還是會有第二 from employee; -- 求出每個部門薪資排在前三名的員工- 分組求TOPN --首先下面這個方法可以么? select dname,ename,salary,dense_rank() over(partition by dname order by salary desc) as rnfrom employee, where rn <= 3; -- 要知道是先執行from employee,后立刻執行where,但是此時根本不知道rn是什么根本沒辦法編譯成功-- 所以我們應該改成下面這種寫法 select * from -- 先執行form (select dname,ename,salary,dense_rank() over(partition by dname order by salary desc) as rn,-- 這里只是拿dense_rank()來示范而已from employee )t where t.rn <= 3; -- from后執行where -- 對所有員工進行全局排序(不分組) -- 不加partition by表示全局排序 select dname,ename,salary,dense_rank() over( order by salary desc) as rn from employee;🌭開窗聚合函數- SUM,AVG,MIN,MAX
概念:
在窗口中每條記錄動態地應用聚合函數(SUM()、AVG()、MAX()、MIN()、COUNT()),可以動態計算在指定的窗口內的各種聚合函數值。
select dname,ename,hiredate,salary, sum(salary) over(partition by dname) as pv3 from employee; -- 如果沒有order by排序語句 默認把分組內的所有數據進行sum操作
select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between unbounded preceding and current row) as c1 -- rows between unbounded preceding and current row的意思是從默認開始行加到當前行 from employee;
select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between 3 preceding and current row) as c1-- rows between 3 preceding and current row從上面三行加到當前行 from employee;
select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between 3 preceding and 1 following) as c1 -- rows between 3 preceding and 1 following上面三行加當前行加下面一行 from employee;
select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between current row and unbounded following) as c1 -- rows between current row and unbounded following當前行加到最后 from employee;
🌭分布函數- CUME_DIST和PERCENT_RANK
介紹-CUME_DIST
用途:分組內小于、等于當前rank值的行數 / 分組內總行數
應用場景:查詢小于等于當前薪資(salary)的比例
介紹-PERCENT_RANK
用途:每行按照公式(rank-1) / (rows-1)進行計算。其中,rank為RANK()函數產生的序號,rows為當前窗口的記錄總行數
應用場景:不常用
🌭前后函數- LAG和LEAD
介紹
用途:返回位于當前行的前n行(LAG(expr,n))或后n行(LEAD(expr,n))的expr的值
應用場景:查詢前1名同學的成績和當前同學成績的差值
-- lead的用法 select dname,ename,hiredate,salary,lead(hiredate,1,'2000-01-01') over(partition by dname order by hiredate) as last_1_time,lead(hiredate,2) over(partition by dname order by hiredate) as last_2_time from employee;
🌭頭尾函數- FIRST_VALUE和LAST_VALUE
介紹
用途:返回第一個(FIRST_VALUE(expr))或最后一個(LAST_VALUE(expr))expr的值
應用場景:截止到當前,按照日期排序查詢第1個入職和最后1個入職員工的薪資
🌭其他函數– NTH_VALUE(expr, n)、NTILE(n)
介紹-NTH_VALUE(expr,n)
用途:返回窗口中第n個expr的值。expr可以是表達式,也可以是列名
應用場景:截止到當前薪資,顯示每個員工的薪資中排名第2或者第3的薪資
介紹–NTILE
用途:將分區中的有序數據分為n個等級,記錄等級數
應用場景:將每個部門員工按照入職日期分成3組
-- 取出每個部門的第一組員工 select * from (SELECT dname,ename,hiredate,salary,NTILE(3) OVER(PARTITION BY dname ORDER BY hiredate ) AS rn FROM employee )t where t.rn = 1;
?
總結
- 上一篇: vs为什么打了断点不断_2019世界羽毛
- 下一篇: linux cmake编译源码,linu