日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

我在b站学数据库 (九):函数

發布時間:2023/12/20 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我在b站学数据库 (九):函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上一篇:我在b站學數據庫 (八):多表操作練習

函數分類
聚合函數、數學函數、字符串函數、日期函數、控制流函數、窗口函數

一、聚合函數
1、介紹
聚合函數主要由:count,sum,min,max,avg,這些聚合函數(之前有),不再重復。另外一個函數:group_concat(),該函數用戶實現行的合并
2、格式
group_concat([distinct] 字段名 [order by 排序字段 asc/desc] [separator ‘分隔符’])
說明:
(1)distinct可以排除重復值。
(2)如果需要對結果中的值進行排序,可以使用order by子句。
(3)separator是一個字符串值,默認為逗號。

3、例
(1)數據準備

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,'銷售部');

(2)操作

-- 將所有員工的名字合并成一行 select group_concat(emp_name) 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;


二、數學函數
1、abs():返回絕對值

select abs(-10); #10 select abs(-10); #10

2、ceil():返回大于或等于的最小整數(向上取整)

select ceil(1.1); #2 select ceil(1.0); #1

3、floor():返回小于或等于的最大整數(向下取整)

select floor(1.1); #1 select floor(1.9); #1

4、greatest(expr1,expr2…):取列表最大值

select greatest(1,2,3); #3

5、least(expr1,expr2…):取列表最小值

select least(1,2,3); #1

6、mod(x,y):返回x除以y以后的余數(取模)

select mod(5,2); #1

7、pow(x,y):返回x的y次方

select pow(2,3) #8

8、rand():返回0到1的隨機數

select rand() #0.93099

9、round(x):返回離x最近的整數(遵循四舍五入)

select round(1.23456) #1

10、round(x,y):返回指定位數的小數(遵循四舍五入)

select round(1.23456,3) #1.235

11、truncate(x,y):返回數值x保留到小數點后y位的值

select truncate(1.23456,3) #1.234

注意:與round最大的區別是不會進行四舍五入

三、字符串函數
1、char_length(s):返回字符串s的字符數

select char_length('hello'); #5 select char_length('你好嗎'); #3 #注意:---length取長度,返回的單位是字節 select length('hello'); #5 select length('你好嗎'); #9 一個漢字3個字節

2、character——length(s):返回字符串s的字符數
同上
3、concat(s1,s2…sn):字符串s1,s2等多個字符串合并為一個字符串

select concat ('hello','world');


4、concat_ws(x,s1,s2…sn):同上函數,但是每個字符串之間要加上x,x可以是分隔符

select concat_ws ('-','hello','world');

5、field(s,s1,s2…):返回第一個字符串s
在字符串列表(s1,s2…)中的第一次位置

select field('a','a','b','c'); #1 select field('b','a','b','c'); #2

6、ltrim(s):去掉字符串s開始處的空格

select ltrim(' aaaa'); #去除左邊空格 select rtrim(' aaaa '); #去除右邊空格 select trim(' aaaa '); #去除兩邊空格



7、mid(s,n,len):從字符串s的n位置截取長度為len的子字符串,同substring(s,n,len)

select mid("helloworld",2,3); #從第二個字符開始截取,截取長度為3


8、position(s1 in s):從字符串s中獲取s1的開始位置

select position('abc'in 'habcelloworld'); #2

9、replace(s,s1,s2):將字符串s2代替字符串s中的字符串s1

select replace('helloaaaworld','aaa','bbb');

10、reverse(s):將字符串s的順序反過來

select reverse('hello');


11、right(s,n):返回字符串s的后n個字符

select right('hello',3); #返回最后三個字符

12、strcmp(s1,s2):比較字符串s1和s2,如果s1
與s2相等返回0,如果s1>s2返回1,如果s1<s2返回-1。

select strcmp('hello','world'); #-1

13、substr(s,start,length):從字符串s的start位置截取長度為length的子字符串

select substr('hello',2,3); # 從第二個字符開始截取,截取三個字符

14、substring(s,start,length):從字符串s的start位置截取長度為length的子字符串
同上
15、ucase(s):將字符串轉換為大寫
16、upper(s):將字符串轉換為大寫

select ucase("helloworld"); select upper("helloworld");

17、lcase(s):將字符串s的所有字母變成小寫字母
18、lower(s):將字符串s的所有字母變成小寫字母

select lcase("HELLOWORLD"); select lower("HELLOWORLD");

四、日期函數
1、unix_timestamp():返回從1970-01-01-00:00:00到當前的毫秒值

select unix_timestamp();

2、unix_timestamp(DATE):將指定日期轉換為毫秒值時間

select unix_timestamp('2022-01-01 08:08:08');

3、from_unixtime(bigint unixtime[,stringformat]):將毫秒值時間轉為指定格式日期

select from_unixtime(88888888,'%Y-%m-%d %H:%i:%s');

4、curdate():返回當前日期

select curdate();`5、current_date():返回當前日期```python select current_date();

6、current_time():返回當前時間

select current_time();

7、curtime():返回當前時間

select curtime();

8、current_timestamp():返回當前日期和時間

select current_timestamp();

9、date():從日期或日期時間表達式中提取日期值(年月日)

select date('2022-01-01 08:08:08');

10、datediff(d1,d2):計算日期d1到d2之間相隔的天數

select datediff('2022-01-01','2000-08-08');

11、timediff(time1,time2):計算時間差值(秒級)

select timediff('08:08:08','06:06:06');

12、date_format(d,f):按表達式f的要求顯示日期d

select date_format('2022-1-1 1:1:1','%Y-%m-%d %H:%i:%s');

13、str_to_date(string,format_mask):將字符串轉變為日期

select str_to_date('2022-1-1 1:1:1','%Y-%m-%d %H:%i:%s');

14、date_sub(date,interval expr type):函數從日期減去指定的時間間隔

select date_sub('2022-01-01',interval 2 day); #將日期進行加法 select date_add('2022-01-01',interval 2 day); #將日期進行加法

15、從日期中獲取

select extract(hour from '2021-12-12 08:08:08'); #獲取小時 select extract(year from '2021-12-12 08:08:08'); #獲取年 select extract(month from '2021-12-12 08:08:08'); #獲取月

16、獲取指定日期的最后一天

select last_day('2022-01-01');

17、獲取指定年份和天數的日期

select makedate('2022',88);

18、根據日期獲取信息

select monthname('2020-02-02 08:08:08'); #獲取月份的英文 select dayname(''2020-02-02 08:08:08'') #獲取周幾 select dayofmonth(''2020-02-02 08:08:08'') #獲取當月的第幾天

五、控制流函數
1、if(expr,v1,v2):如果表達式expr成立,返回結果v1,否則返回結果v2。

select if(5>3,'大于','小于'); #大于

2、ifnull(v1,v2):如果v1的值不為null,則返回v1,否則返回v2。

select ifnull(5,0); #5 select ifnull(null,0); #0

3、isnull(expression):判斷表達式是否為null。

select isnull(5); #0 select isnull(null); #1

4、nullif(expr1,expr2):比較兩個字符串,如果字符串expr1與expr2相等,返回null,否則返回expr1。

select nullif(12,12) #null select nullif(12,13) #12

5、case when語句
格式:
case expression
when condition 1 then result 1
when condition 2 then result 2

else result
end
解釋:case表示函數開始,end表示函數結束。如果condition1成立,則返回result1,如果condition2成立則返回result2,當全部不成立,則返回result,而當有一個成立之后,后面的就不執行了。
例:

-- 創建訂單表 create table orders(oid int primary key, -- 訂單idprice 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 when payType=1 then '微信支付' when payType=2 then '支付寶支付' when payType=3 then '銀行卡支付' else '其他支付方式' end as payTypeStr from orders; -- 方式2 select * , case payTypewhen 1 then '微信支付' when 2 then '支付寶支付' when 3 then '銀行卡支付' else '其他支付方式' end as payTypeStr from orders;

六、窗口函數(8.0新增)
1、概念
非聚合窗口函數是相對于聚函數來說的。聚合函數是對一組數據計算后返回單個值(即分組),非聚合函數一次只會處理一行數據。窗口聚合函數在行記錄上計算某個字段的結果時,可將窗口范圍內的數據輸入到聚合函數中,并不改變行數。

2、序號函數
(1)序號函數有三個:row_number()、rank()、dense_rank()
(2)格式:
row_number()|rank()|dense_rank() over (
partition by …
order by …
)
(3)例

#數據準備 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);#操作 -- 對每個部門的員工按照薪資排序,并給出排名 select dname, ename, salary, row_number() over(partition by dname order by salary desc) as rn from employee;

-- 對每個部門的員工按照薪資排序,并給出排名 rank select dname, ename, salary, rank() over(partition by dname order by salary desc) as rn from employee;

-- 對每個部門的員工按照薪資排序,并給出排名 dense-rank select dname, ename, salary, dense_rank() over(partition by dname order by salary desc) as rn from employee;


注意:仔細觀察三個結果的序號,進行區分

--求出每個部門薪資排在前三名的員工- 分組求TOPN select * from (select dname,ename,salary,dense_rank() over(partition by dname order by salary desc) as rnfrom employee )t where t.rn <= 3 -- 對所有員工進行全局排序(不分組) -- 不加partition by表示全局排序 select dname,ename,salary,dense_rank() over( order by salary desc) as rn from employee;

3、開窗聚合函數
(1)概念
在窗口中每條記錄動態地應用聚合函數(SUM()、AVG()、MAX()、MIN()、COUNT()),可以動態計算在指定的窗口內的各種聚合函數值。
(2)例(以sum為例)

select dname,ename,salary,sum(salary) over(partition by dname order by hiredate) as c1 from employee;


注意:結果為第一行salary加到當前行

select dname, ename, hiredate, salary sum(pv) over(partition by dname) as c1 from employee; -- 如果沒有order by排序語句 默認把分組內的所有數據進行sum操作

select dname,ename,hiredate,salary,sum(salary) over(partition by dname order by hiredate rows between unbounded preceding and current row) as c1 from employee; #從開頭加到當前行

select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between 3 preceding and current row) as c1 from employee; #從當前行的前三行加到當前行

#同理 從當前的前三行加到當前的后一行(包括本行) select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between 3 preceding and 1 following) as c1 from employee;#從當前行加到最后一行 select dname,ename,salary,sum(salary) over(partition by dname order by hiredate rows between current row and unbounded following) as c1 from employee;

4、分布函數(CUME_DIST)
(1)用途:分組內小于、等于當前rank值的行數 / 分組內總行數
(2)應用場景:查詢小于等于當前薪資(salary)的比例
(3)例

select dname,ename,salary,cume_dist() over(order by salary) as rn1, -- 沒有partition語句 所有的數據位于一組cume_dist() over(partition by dname order by salary) as rn2 from employee;


解釋:
rn1 以第一行0.25為例,因為沒有分組,所以在所有數據中小于等于3000的行數除以總行數。即3/12=0.25。
rn2以第一行0.166666666…為例,因為以dname分組的,所以在一組數據中小于等于3000的行數除以總行數。即1/6=0.1666…

5、分布函數(PERCENT_RANK)
(1)用途:每行按照公式(rank-1) / (rows-1)進行計算。其中,rank為RANK()函數產生的序號,rows為當前窗口的記錄總行數
(2)應用場景:不常用
(3)例

select dname,ename,salary,rank() over(partition by dname order by salary desc ) as rn,percent_rank() over(partition by dname order by salary desc ) as rn2 from employee;


解釋:
rn2:
第一行: (1 - 1) / (6 - 1) = 0
第二行: (1 - 1) / (6 - 1) = 0
第三行: (3 - 1) / (6 - 1) = 0.4

6、前后函數(LAG和LEAD)
(1)用途:返回位于當前行的前n行(LAG(expr,n))或后n行(LEAD(expr,n))的expr的值
(2)應用場景:查詢前1名同學的成績和當前同學成績的差值
(3)例

-- lag的用法 select dname,ename,hiredate,salary,lag(hiredate,1,'2000-01-01') over(partition by dname order by hiredate) as last_1_time,#前一行的值放到當前行,沒有的話有默認值'2000-01-01'lag(hiredate,2) over(partition by dname order by hiredate) as last_2_time #前兩行的值放到當前行,默認值為null from employee;

解釋:
last_1_time: 指定了往上第1行的值,default為’2000-01-01’ 。第一行,往上1行為null,因此取默認值 ‘2000-01-01’

last_2_time: 指定了往上第2行的值,為指定默認值
第一行,往上2行為null

-- 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;


解釋:lead同作用lag,只是lead是向下。

7、頭尾函數
(1)用途:返回第一個(FIRST_VALUE(expr))或最后一個(LAST_VALUE(expr))expr的值
(2)應用場景:截止到當前,按照日期排序查詢第1個入職和最后1個入職員工的薪資
(3)例

-- 注意, 如果不指定ORDER BY,則進行排序混亂,會出現錯誤的結果 selectdname,ename,hiredate,salary,first_value(salary) over(partition by dname order by hiredate) as first,last_value(salary) over(partition by dname order by hiredate) as last from employee;


解釋:
first1:返回截至到當前,按照日期排序查詢第一個入職的員工薪資
last1:返回截至到當前,按照日期排序查詢第一個入職的員工薪資

8、其他函數(nth_value(expr,n))
(1)用途:返回窗口中第n個expr的值。expr可以是表達式,也可以是列名
(2)應用場景:截止到當前薪資,顯示每個員工的薪資中排名第2或者第3的薪資
(3)例

-- 查詢每個部門截止目前薪資排在第二和第三的員工信息 select dname,ename,hiredate,salary,nth_value(salary,2) over(partition by dname order by hiredate) as second_score,nth_value(salary,3) over(partition by dname order by hiredate) as third_score from employee


解釋:
返回截至當前,按入職日期排第二和第三的員工薪資

9、其他函數(ntile)
(1)用途:將分區中的有序數據分為n個等級,記錄等級數
(2)應用場景:將每個部門員工按照入職日期分成3組
(3)例

-- 根據入職日期將每個部門的員工分成3組 select dname,ename,hiredate,salary, ntile(3) over(partition by dname order by hiredate ) as rn from employee;

-- 取出每個部門的第一組員工 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;

下一篇:我在b站學數據庫 (十):視圖

總結

以上是生活随笔為你收集整理的我在b站学数据库 (九):函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。