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

歡迎訪問 生活随笔!

生活随笔

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

数据库

【MySQL】函数

發布時間:2023/12/20 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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. 聚合函數

概述:

  • 在MySQL中,聚合函數主要由:count,sum,min,max,avg,這些聚合函數我們之前都學過,不再重復。這里我們學習另外一個函數:group_concat ( ),該函數用戶實現行的合并
  • group_concat() 函數首先根據group by指定的列進行分組,并且用分隔符分隔,將同一個分組中的值連接起來,返回一個字符串結果。
  • 語法:
    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) from emp;


    -- 指定分隔符合并 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. 數學函數


    例子:

    -- 求絕對值 selectabs ( -10); selectabs (10); selectabs(表示式或者字段) from; -- 向上取整 select ceil(1.1); -- 2 select ceil(1.0); -- 1 -- 向下取整 select floor(1.1); -- 1 select floor(1.9); -- 1 -- 取列表最大值 select greatest(1,2,3); -- 3 -- 取列表最小值 select least(1,2,3); -- 1-- 取模 select mod ( 5,2);-- 1-- 取x的y次方 select power(2,3); -- 8-- 取隨機數 select rand( ) ;-- 取隨機數在100以內的整數 select floor(rand() *100);-- 將小數的四舍五入 select round( 3.5415);-- 4 -- 將小數的四舍五入,保留三位小數 select round( 3.5415);-- 3.542-- 將小數直接截取到指定位數 select truncate(3.1415,3); -- 3.141

    🥂3. 字符串函數


    例子:

    -- 字符串函數 -- 1:獲取字符串字符個數 select char_length( ' hello' ); -- 5 select char_length('你好嗎'); -- 3 -- length取長度,返回的單位是字節 select length( ' hello'); -- 5 select length('你好嗎'); -- 9 每個漢字是3個字符 -- 2:字符串合并 select concat( ' hello' , 'world' );-- helloworld select concat(c1,c2) from table_name; -- 2:指定分隔符進行字符串合并 select concat_ws( '-', 'hello ' , ' world ' ) ; -- hello-world -- 3:返回字符串在列表中第一次出現的位置 select field( 'aaa ' , 'aaa' , ' bbb ' , 'ccc'); -- 1 select field( ' bbb' , 'aaa ' , ' bbb' , 'ccc ' ); -- 2 -- 4:去除字符串左邊空格 select ltrim( 'aaaa'); -- 去除左邊空格 select rtrim( 'aaaa'); -- 去除右邊空格 select trim( 'aaaa' ); -- 去除兩端空格 -- 5:字符串截取 select mid("helloworld",2,3); -- 從第二個字符開始截取,截取長度為3 -- 6:獲取字符串A在字符串B中第一次出現的位置 select position( 'abc' in 'habcelloabcworld ' );-- 2 -- 7:字符串替換 select replace( 'aaahelloaaaworld' , 'aaa' , 'bbb' );-- bbbhellobbbworld -- 8:字符串翻轉 select reverse( 'hello');-- olleh-- 9:返回字符串的后幾個字符 select right( 'hello',3); -- 返回最后三個字符 llo -- 10:字符串比較 select strcmp( ' hello' , 'world ' );-- -1 和c語言一樣也是先比較第一個不一樣的字符然后看字符碼 -- 11:字符串截取 select substr( 'hello',2,3); -- ell 從第二個字符開始截取,截取三個字符 select substr( 'hello',2,3); -- ell 從第二個字符開始截取,截取三個字符 -- 12:將小寫轉大寫 select ucase ( "helloworld" );-- HELLOWORD select upper( "helloworld" ) ;-- HELLOWORD -- 13:將大寫轉為小寫 select lcase( "HELLOWORD" );-- helloword select lower("HELLOWORD" );-- helloword

    🥂4. 日期函數



    -- 日期函數 -- 1:獲取時間戳(毫秒值) select unix_timestamp(); -- 2:將一個日期字符串轉為毫秒值 select unix_timestamp( '2021-12-21 08:08:08'); -- 3:將時間戳毫秒值轉為指定格式的日期 select from_unixtime(1640045288, '%Y-%m-%d %H:%i:%s')-- %Y-%m-%d %H:%i:%s年月日時分秒 -- 4:獲取當前的年月日 select curdate(); select current_date(); -- 5:獲取當前的時分秒 SELECT CURRENT_TIME();SELECT CURTIME(); -- 6:獲取年月日和時分秒 SELECT CURRENT_TIMESTAMP(); -- 7:從日期字符串中獲取年月日 select date('2022-12-12 12:34:56'); -- 8:獲取日期之間的差值 select datediff('2021-12-23','2008-08-08'); select datediff(current_date(),'2008-08-08'); -- 9:獲取時間的差值(秒級) select timediff( '12:12:34', '10:18:56'); -- 01:53:38 -- 10:日期格式化 select date_format('2021-1-1 1:1:1',' %Y-%m-%d %H:%i:%s');-- 2021-01-01 01:01:01 select date_format('2021-12-13 11:11:11','%Y-%m-%d %H:%i:%s'); -- 11:將字符串轉為日期 select str_to_date('2021-12-13 11:11:11', '%Y-%m-%d %H:%i:%s'); -- 12:將日期進行減法 -- 日期向前跳轉 select date_sub('2021-10-01' ,interval 2 day) ;select date_sub('2021-10-01',interval 2 month); -- 13:將日期進行加法 -- 日期向后跳轉 select date_add('2021-10-01',interval 2 day); select date_add('2021-10-01',interval 2 month); -- 14:從日期中獲取小時 select extract(hour from '2021-12-13 11:12:13'); select extract(year from '2021-12-13 11:12:13'); select extract(month from '2021-12-13 11:12:13'); -- 15:獲取給定日期所在月的最后一天 select last_day ('2021-08-13');-- 2021-08-31 -- 16:獲取指定年份和天數的日期 select makedate( ' 2021',53);-- 2021-02-22 -- 17:根據日期獲取年月日、時分秒 select year('2021-12-13 11:12:13' ); select month('2021-12-13 11:12:13'); select minute('2021-12-1311:12:13'); select quarter('2021-12-13 11:12:13');-- 4 獲取季度-- 18:根據日期獲取信息 SELECT MONTHNAME( '2021-12-13 11:12:13');-- 獲取月份的英文 SELECT DAYNAME( '2021-12-13 11:12:13' ); -- 獲取周幾: Monday SELECT DAYOFMONTH( '2021-12-13 11:12:13'); -- 當月的第幾天 SELECT DAYOFWEEK( '2021-12-13 11:12:13'); -- 1:周日2周一 SELECT DAYOFYEAR( '2021-12-13 11:12:13'); -- 獲取一年的第幾天 SELECT wEEK( '2021-12-13 11:12:13'); SELECT WEEK( '2021-01-01 11:12:13'); SELECT WEEK( '2021-12-31 11:12:13' ); SELECT YEARWEEK( '2021-3-01'); SELECT NOW();

    🥂5. 控制流函數

    -- 控制流函數 -- IF select if(5>3,'大于','小于'); select *,if(score >= 85, '優秀','及格') flag from score;


    下面是if語句:

    -- IFNULL select ifnull(5,0); -- 5 select ifnul1(NULL,0);-- 0 select *,ifnull(comm,0) comm_flag from emp ; -- ISNULL select isnull(5); -- 0 select isnul1(NULL); -- 1 -- NULLIF select nullif(12,12); -- null select nullif(12,10); -- 12 返回第一個值

    下面是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 order by hiredate) as pv1 -- 默認從第一行加到當前行 from employee;


    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)的比例

    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: 沒有partition,所有數據均為1組,總行數為12,第一行:小于等于3000的行數為3,因此,3/12=0.25第二行:小于等于4000的行數為5,因此,5/12=0.4166666666666667 rn2: 按照部門分組,dname='研發部'的行數為6,第一行:研發部小于等于3000的行數為1,因此,1/6=0.16666666666666666 */


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

    select dname,ename,salary,rank() over(partition by dname order by salary desc ) as rank值,percent_rank() over(partition by dname order by salary desc ) as rn2 from employee;/*當前rank值-1 / 總行數-1rn2:第一行: (1 - 1) / (6 - 1) = 0第二行: (1 - 1) / (6 - 1) = 0第三行: (3 - 1) / (6 - 1) = 0.4 */


    🌭前后函數- LAG和LEAD

    介紹
    用途:返回位于當前行的前n行(LAG(expr,n))或后n行(LEAD(expr,n))的expr的值
    應用場景:查詢前1名同學的成績和當前同學成績的差值

    -- 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是自己設定的默認值,如果不設置默認為nulllag(hiredate,2) over(partition by dname order by hiredate) as last_2_time from employee; /* last_1_time: 指定了往上第1行的值,default為'2000-01-01' 第一行,往上1行為null,因此取默認值 '2000-01-01'第二行,往上1行值為第一行值,2021-11-01 第三行,往上1行值為第二行值,2021-11-02 last_2_time: 指定了往上第2行的值,為指定默認值第一行,往上2行為null第二行,往上2行為null第四行,往上2行為第二行值,2021-11-01 第七行,往上2行為第五行值,2021-11-02 。。。 */


    -- 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個入職員工的薪資

    -- 注意, 如果不指定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; /*first_value(salary)是開始時的薪資last_value(salary)是到本行為止最后一個位置的薪資 */


    🌭其他函數– NTH_VALUE(expr, n)、NTILE(n)

    介紹-NTH_VALUE(expr,n)
    用途:返回窗口中第n個expr的值。expr可以是表達式,也可以是列名
    應用場景:截止到當前薪資,顯示每個員工的薪資中排名第2或者第3的薪資

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


    介紹–NTILE
    用途:將分區中的有序數據分為n個等級,記錄等級數
    應用場景:將每個部門員工按照入職日期分成3組

    -- 根據入職日期將每個部門的員工分成3組 select dname,ename,hiredate,salary, ntile(3) over(partition by dname order by hiredate ) as rn , ntile(4) 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;


    ?

    總結

    以上是生活随笔為你收集整理的【MySQL】函数的全部內容,希望文章能夠幫你解決所遇到的問題。

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