mysql函數與分組

前言

1️⃣ :mysql環境準備

2️⃣ :簡單的表查詢

3️⃣ :通配符+正則表達式

第一部分:我們準備環境:安裝數據庫+創建數據庫+創建用戶+授權。

第二部分:環境準備好後,進行簡單的單表查詢:導入表+表查詢。

第三部分:通配符和正則表達式,增強where的篩選功能。

現在是第四部分:參考《sql必知必會》chapter10~13,字段+函數+分組

增強查詢列那部分功能和對查詢進行分組彙總。


摘要與總結

有時候,我們並不是希望直接將列返回。而是將列,進行計算處理。

這裏處理過程,如果放在服務器端,我們把這個列稱爲字段。在客戶端看來,字段和列完全沒區別。

當列處理過程比較複雜的時候,我們引入了函數

有的操作函數是整理總結類型。按照不同組彙總,進行分組操作。

順其自然的對比,行過濾(where)和分組過濾(having)的區別。默認情況是所有行是不同的組。WHERE過濾行,而HAVING過濾分組。



字段

字段(field) 基本上與列( column) 的意思相同,經常互換使用。

# 比如我們想得到總價格。數據庫中沒有直接存儲,但是可以計算得出
mysql> select num*price from products;

num*prict 就是字段啦。

只有數據庫知道SELECT語句中哪些列是實際的表列,哪些列是計算字段。從客戶機(如應用程序)的角度來看,計算字段的數據是以與其他列的數據相同的方式返回的。

當然,我們可以把數據傳回客戶端,在客戶端進行處理。

但一般來說,在數據庫服務器上完成這些操作比在客戶機中完成要快得多,因爲DBMS是設計來快速有效地完成這種處理的。

關於字段處理:計算字段、拼接字段、使用別名

# 計算字段,使用別名
mysql> select num*price AS total_price from products;
# 拼接字段,把商家名和商家地址,按照“商家(地址)”格式輸出
mysql> SELECT concat(vend_name,'(',vend_address,')') FROM vendors;


函數

上面有對字段的計算。但是當計算比較複雜的時候,咋整?

曉過編程語言的都知道,要用函數。

即:當操作這個字段比較複雜的時候,直接操作就不合適了。所以必須引進函數。處理文本、處理日期時間、數值處理。

函數這裏被分成兩類:數據處理函數、彙總函數

數據處理函數

  1. 文本處理函數

    在這裏插入圖片描述

在這裏插入圖片描述

  1. 日期處理函數

在這裏插入圖片描述

  1. 數值處理函數

    在這裏插入圖片描述

看到這裏,我們順道會想到,能否使用自定義的函數,以及如何使用。

當然可以。可以參考下面這兩篇文章。

數據庫之自定義函數
函數與存儲過程

但是

函數的可移植性卻不強。幾乎每種主要的DBMS的實現都支持其他實現不支持的函數,而且有時差異還很大。

爲了代碼的可移植,許多SQL程序員不贊成使用特殊實現的功能。雖然這樣做很有好處,但不總是利於應用程序的性能。如果不使用這些函數,編寫某些應用程序代碼會很艱難。必須利用其他方法來實現DBMS非常有效地完成的工作。

如果你決定使用函數,應該保證做好代碼註釋,以便以後你(或其他人)能確切地知道所編寫SQL代碼的含義。


彙總數據函數

雖然,彙總數據的函數也是函數,但是它應該在分組上起作用。

當然它們也可以直接使用。因爲默認的是每一行是一個分組。

關於分組的內容,我們放在下一節。暫時不影響理解。

我們經常需要彙總數據而不用把它們實際檢索出來,爲此MySQL提供了專門的函數。使用這些函數, MySQL查詢可用於檢索數據,以便分析和報表生成。

參考:help countSQL中distinct的用法

在這裏插入圖片描述

# 對所有的價格取平均
mysql> SELECT AVG(prod_price) AS avg_prod_price FROM products

# 如果一章表中,有相同的產品。我們得過濾下。保證得出的是每個物品的平均價格
# 這裏得用下子查詢
mysql> SELECT AVG(prod_price) AS avg_prod_price FROM products 
WHERE prod_name IN(SELECT DISTINCT prod_name FROM products);


分組數據

分組允許把數據分爲多個邏輯組,以便能對每個組進行聚集計算。(聚集計算使用的是上面“彙總數據函數”)

使用GROUP BY創建分組;使用HAVING過濾分組;

使用WITH ROLLUP時,將會在所有記錄的最後加上一條記錄。這條記錄是上面所有記錄的總和。

參考:MySQL對數據表進行分組查詢(GROUP BY)

SELECT vend_id, COUNT(*) AS num_prods
FROM products
GROUP BY vend_id
HAVING COUNT(*)>=2
WITH ROLLUP; 

這時候,我們會注意到,WHEREHAVING都是篩選,它們有什麼不同。

  • 因爲WHERE過濾指定的是行而不是分組。事實上, WHERE沒有分組的概念。

  • 目前爲止所學過的所有類型的WHERE子句都可以用HAVING來替代。唯一的差別是WHERE過濾行,而HAVING過濾分組.

  • HAVING支持所有WHERE操作符。它們的句法是相同的,只是關鍵字有差別。

  • 當然它們可以同時出現。鐵路警察,各管各的。

    # 列出具有2個(含)以上、價格爲10(含)以上的產品的供應商
    SELECT vend_id,COUNT(*) FROM products
    WHERE prod_price>=10
    GROUP BY vend_id
    HAVING COUNT(*)>=2
    ORDER BY vend_id;
    
    # 或者這麼寫
    SELECT vend_id,COUNT(*) AS vend_nums FROM products
    WHERE prod_price>=10
    GROUP BY vend_id
    HAVING vend_nums>=2
    ORDER BY vend_nums;
    


小總結:SELECT子句順序

在這裏插入圖片描述
在這裏插入圖片描述



參考文章

聊一聊Mysql中的字符串拼接函數

數據庫之自定義函數

函數與存儲過程

聚集函數( aggregate function)

SQL中distinct的用法

MySQL對數據表進行分組查詢(GROUP BY)

MySQL中DISTINCT與GROUP BY計數原理分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章