前言
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;
函數
上面有對字段的計算。但是當計算比較複雜的時候,咋整?
曉過編程語言的都知道,要用函數。
即:當操作這個字段比較複雜的時候,直接操作就不合適了。所以必須引進函數。處理文本、處理日期時間、數值處理。
函數這裏被分成兩類:數據處理函數、彙總函數
數據處理函數
-
文本處理函數
- 日期處理函數
-
數值處理函數
看到這裏,我們順道會想到,能否使用自定義的函數,以及如何使用。
當然可以。可以參考下面這兩篇文章。
但是
函數的可移植性卻不強。幾乎每種主要的DBMS的實現都支持其他實現不支持的函數,而且有時差異還很大。
爲了代碼的可移植,許多SQL程序員不贊成使用特殊實現的功能。雖然這樣做很有好處,但不總是利於應用程序的性能。如果不使用這些函數,編寫某些應用程序代碼會很艱難。必須利用其他方法來實現DBMS非常有效地完成的工作。
如果你決定使用函數,應該保證做好代碼註釋,以便以後你(或其他人)能確切地知道所編寫SQL代碼的含義。
彙總數據函數
雖然,彙總數據的函數也是函數,但是它應該在分組上起作用。
當然它們也可以直接使用。因爲默認的是每一行是一個分組。
關於分組的內容,我們放在下一節。暫時不影響理解。
我們經常需要彙總數據而不用把它們實際檢索出來,爲此MySQL提供了專門的函數。使用這些函數, MySQL查詢可用於檢索數據,以便分析和報表生成。
參考:help count 、SQL中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
時,將會在所有記錄的最後加上一條記錄。這條記錄是上面所有記錄的總和。
SELECT vend_id, COUNT(*) AS num_prods
FROM products
GROUP BY vend_id
HAVING COUNT(*)>=2
WITH ROLLUP;
這時候,我們會注意到,WHERE
和HAVING
都是篩選,它們有什麼不同。
-
因爲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子句順序