1. 程式人生 > >06 mysql 處理函式 聚合函式 分組函式

06 mysql 處理函式 聚合函式 分組函式

上節介紹了排序函式,這節介紹其他常用的函式,其實mysql中內建的函式有好多,有興趣的或者想要深入掌握mysql可以檢視文末的連結

 

1 處理函式

MySQL提供了一些函式可以對查詢出的結果進行處理,處理函式是對每行資料進行處理的,可以放在select之後 where之前,也可以用在where子句中

下面介紹一些常用的資料處理函式

       1  處理字串的函式:

lower(s)轉換為小寫

upper(s)轉換為大寫

substr(s, start, length)擷取子串,從字串 s 的 start 位置擷取長度為 length 的子字串

length(s)獲取欄位長度

trim(s)  去掉字串 s 開始和結尾處的空格,注:MySQL存放資料時,預設去除欄位後面的空格,原因是MySQL語法鬆散

ifnull(v1,v2)   如果 v1 的值不為 NULL,則返回 v1,否則返回 v2

示例:

--字串處理函式部分
-- 查詢員工編號,員工姓名的小寫樣式(起別名ename),工作
SELECT employeenumber,LOWER(employeename) AS ename,job FROM employee;
-- 查詢員工編號,員工姓名的大寫樣式(起別名ename),工作
SELECT employeenumber,UPPER(employeename) AS ename,job FROM employee;

-- 查詢員工編號,姓名,姓名中的第二個字元(別名secname) 
SELECT employeenumber,employeename,SUBSTR(employeename,2,1) secname FROM employee;
-- -- 查詢員工姓名的第二個字元是'A'的員工的所有資訊
SELECT * FROM employee WHERE SUBSTR(employeename,2,1)='A';

-- 查詢員工編號,姓名,姓名的長度
SELECT employeenumber,employeename,LENGTH(employeename) FROM employee;

-- 查詢員工中姓名等於 ' smith '去除前後空格後的字串的員工資訊
SELECT * FROM employee  WHERE TRIM(' smith ')=employeename;
-- 查詢員工中工作是 ' manager '去除前後空格後的字串的員工資訊
SELECT * FROM employee WHERE job=TRIM(' manager ');

-- 查詢員工編號,工作,薪水,補貼
SELECT employeenumber,job,salary,comm  FROM employee ;
-- 查詢員工編號,工作,薪水,補貼(如果補貼不為null顯示補貼,如果為null顯示0)
SELECT employeenumber,job,salary,IFNULL(comm,0) FROM employee ;
-- 查詢員工編號,工作,薪水+補貼 (起別名totalsalary) 注意:只要和null進行加減運算的結果都是null
SELECT employeenumber,job,salary+comm AS totalsalary  FROM employee ;
-- 查詢員工編號,工作,薪水+補貼(補貼為null顯示0,不為null顯示本來的值)(起別名totalsalary) 
SELECT employeenumber,job,salary+IFNULL(comm,0)  totalsalary FROM employee;

        2  處理數字的函式:

round(數字,保留的小數位數) 四捨五入到要保留的小數點,如果第二個引數不寫,預設舍入到整數位

rand()生成隨機數,生成0到1之間的隨機數,包括0和1兩個數

示例:

-- 數值處理函式部分
-- 查詢員工編號,員工工資(四捨五入保留1位小數)
SELECT employeenumber,ROUND(salary,1) FROM employee;
-- 生成0-1之間的隨機數,包括0和1兩個端點
SELECT RAND();
-- 生成0-100之間的隨機數,包括0和100兩個端點
SELECT ROUND(RAND()*100);
-- 生成0-100之間的整數,個數和employee表中資料條數一樣多
SELECT ROUND(RAND()*100) FROM employee;

        3  處理日期型別的函式:

MySQL中日期作為查詢條件時,可以使用字串為其賦值,預設識別的常用格式有三種:

  • 2016-06-15
  • 2016/06/15
  • 20160615

str_to_date(‘日期字串’,’日期格式’)字串轉日期,

其中日期格式如下:

  •       %Y 代表四位的年份
  •      %y 代表兩位的年份
  •      %m 代表月,格式(01 … 12)
  •     %c 代表月,格式(1 … 12)
  •     %d 代表日
  •     %H 代表24小時制
  •     %h 代表12小時制
  •     %i 代表分種,格式(00 … 59)
  •    %S或%s 代表秒 , 格式(00..59)

date_format(d,f)格式化日期,按表示式 f的要求顯示日期 d

示例:

-- 日期處理函式部分
-- 查詢入職日期為1981-02-20的員工所有資訊
SELECT * FROM employee WHERE hiredate='1981-02-20';
-- 查詢入職日期字串為'1981-20-02'的員工所有資訊,先講字串轉成date型別
SELECT * FROM employee WHERE hiredate=STR_TO_DATE('1981-20-02','%Y-%d-%m');
-- 查詢員工編號,僱傭日期,將僱傭日期按指定格式顯示(如這種格式12-02-1992)
SELECT employeenumber,hiredate,DATE_FORMAT(hiredate,'%d-%m-%Y') FROM employee;

       4   高階函式

CASE expression
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
   ...
    WHEN conditionN THEN resultN
    ELSE result
END

 CASE 表示函式開始,END 表示函式結束。如果 condition1 成立,則返回 result1, 如果 condition2 成立,則返回 result2,當全部不成立則返回 result,而當有一個成立之後,後面的就不執行了。

示例:


-- 高階函式部分 查詢員工姓名,工作,工資,當工作為namager時,工資*1.5倍,
-- 工作為salesman時,工資*0.5倍,其他員工的工資不變,起別名newsalary 
SELECT
  employeename,
  job,
  salary,
  CASE
    job
    WHEN 'manager'
    THEN salary * 1.5
    WHEN 'SALESMAN'
    THEN salary * 0.5
    ELSE salary
  END AS newsalary
FROM
  employee;

說明:這些函式中有些是MySQL特有的,在其他資料庫管理系統中可能不起作用。

2 聚合函式

聚合函式主要是用來計算指定欄位的值(某列(或者幾列) 返回一個值 或者某組 返回多個值,和組數相對應)

聚合函式在計算時會自動忽略空值(null值),不用手動寫sql將空值排除。如果使用+-*/等運算子時,遇到null值,運算結果也是null

聚合函式不能直接寫在where語句中。

下面介紹常用的聚合函式:

sum(expression)返回指定欄位的總和

-- 查詢所有員工工資之和
  SELECT SUM(salary) FROM employee;
-- 查詢所有員工的補貼之和,會自動忽略null值
  SELECT SUM(comm) FROM employee;
-- 查詢所有員工的工資和補貼之和,這種計算方式不對,因為加號遇到null值為null,聚合函式會忽略掉這些null值
  SELECT SUM(salary+comm) FROM employee;
-- 查詢所有員工的工資和補貼之和,如果補貼為null,按0計算
  SELECT SUM(salary+IFNULL(comm,0)) FROM employee;

avg(expression)返回一個表示式的平均值,expression 是一個欄位

-- 查詢所有員工的平均工資
  SELECT AVG(salary)  AS svasalary FROM employee;

max(expression)返回欄位 expression 中的最大值

min(expression)返回欄位 expression 中的最小值

說明:日期也可以使用max(),min()函式進行比較

 -- 查詢所有員工工資中的最大工資
  SELECT MAX(salary) FROM employee;
-- 查詢所有員工入職日期中最大的那個,離現在最近的那個
  SELECT MAX(hiredate) FROM employee;
-- 查詢所有員工工資中的最大工資
  SELECT MIN(salary) FROM employee;
-- 查詢所有員工入職日期中最小的那個,離現在最遠的那個
  SELECT MIN(hiredate) FROM employee;

count(expression)返回查詢的記錄總數,expression 引數是一個欄位或者 * 號

-- 統計員工個數
  SELECT COUNT(*) FROM employee;
--統計員工中補貼不為null的個數,因為聚合函式會忽略null值
  SELECT COUNT(comm) FROM employee;
-- 統計員工中補貼為null的個數
  SELECT COUNT(*) FROM employee WHERE comm IS NULL;
  --查詢員工個數,最大薪水,最小薪水,平均薪水,和薪水之和
  SELECT COUNT(*) ,MAX(salary),MIN(salary),AVG(salary),SUM(salary) FROM employee;

distinct去除重複記錄

作用:將查詢結果中某一欄位的重複記錄去除掉
用法:distinct 欄位名或 distinct欄位名1, 欄位名2…
注意:distinct只能出現在所有欄位最前面,後面如果有多個欄位先按第一個欄位去重,如果第一個欄位中後面有不同的分類,再將他們依次列出來,多欄位相當於多級分類,或者說將多個欄位相同的記錄去重,只保留一個

示例:

 -- 查詢有哪些工作種類
 SELECT DISTINCT job FROM employee;
-- 查詢工作崗位的個數
  SELECT COUNT(DISTINCT job) FROM employee;
-- 查詢工作崗位的個數,和部門編號的個數
   SELECT COUNT(DISTINCT job) ,COUNT(DISTINCT departmentnumber) FROM employee;
-- 查詢有哪些工作和這些工作崗位中員工姓名的第二個字元
  SELECT DISTINCT job ,SUBSTR(employeename,2,1) FROM employee;
-- 查詢有哪些部門,哪些工作 去除掉部門和工作崗位都重複的記錄
  SELECT DISTINCT departmentnumber,job FROM employee;
  

3 分組函式 group by

group by 語句根據一個或多個列對結果集進行分組。在分組的列上我們可以使用 count(),sum(),avg()等函式。

注:在有group by的DQL詢句中,select語句後面只能跟 聚合函式 + 參與分組的欄位

-- 根據工作分組,查詢工作和該工作的最大工資
SELECT job,MAX(salary) FROM employee GROUP BY job;

-- 根據工作分組,查詢工作和該工作的最大工資,按最大工資的升序排序
SELECT job,MAX(salary) maxsalary FROM employee GROUP BY job ORDER BY maxsalary;

--根據部門編號分組,查詢部門編號,部門的平均工資
SELECT  departmentnumber,AVG(salary) FROM employee GROUP BY departmentnumber;

--根據部門編號和工作分組,查詢部門編號,工作,和該部門該工作的平均工資
SELECT departmentnumber,job,AVG(salary) FROM employee GROUP BY departmentnumber,job;
-- 根據工作分組,查詢工作和該工作的最大工資,過濾掉工作為'manager'的記錄
SELECT job,MAX(salary) FROM employee WHERE job!='manager' GROUP BY job;

 having 過濾

如果想對分組的資料進行過濾,需要使用having子句

注:

1聚合函式不能放在where子句中

2能夠在where後過濾的資料不要放到having中進行過濾,否則影響SQL詢句的執行效率。

示例:

-- 按工作分組,查詢工作和該工作的平均工資,並過濾掉平均工資小於等於2000的記錄
SELECT job,AVG(salary)  AS avgsalary FROM employee GROUP BY job HAVING avgsalary>2000;
-- 過濾掉部門編號為10的記錄,再按工作分組,查詢工作和該工作的平均工資,過濾掉平均工資小於2000的記錄,再根據平均工資按降序排列
SELECT job,AVG(salary) AS avgsalary FROM employee WHERE departmentnumber <> 10 GROUP BY job
HAVING avgsalary > 2000 ORDER BY avgsalary DESC;

where和having的區別:

  • where和having都是為了完成資料的過濾,它們後面都是新增條件;
  • where是在 group by之前完成過濾;
  • having是在group by之後完成過濾;

sql語句的順序:

幾個關鍵字的使用順序依次為 where 、group by 、having、order by.

一個查詢語句的格式為

select expression1,expression2,..  from 表名 where 過濾條件 group by expression having 過濾條件 order by expression;

1、 from 將硬碟上的表文件載入到記憶體

2、 where 將符合條件的資料行摘取出來,生成一張臨時表

3、 group by 根據列中的資料種類,將當前臨時表劃分成若干個新的臨時表

4、 having 可以過濾掉group by生成的不符合條件的臨時表

5、 select 對當前表進行整列讀取

6、 order by 對select生成的臨時表,進行重新排序,生成新的臨時表

7、 limit 對最終生成的臨時表的資料行進行擷取
 

 

參考:小猴子視訊

       http://www.monkey1024.com/database/816

 

 

 

 

 

 

 

處理函式參考連結:http://www.runoob.com/mysql/mysql-functions.html