目錄
1.查詢基礎
SELECT語句基礎
列的查詢
通過 SELECT 語句查詢並選取出必要數據的過程稱爲匹配查詢或查詢(query)。
--基本的SELECT語句
SELECT <列名>,……
FROM <表名>;
該SELECT 語句包含了SELECT 和FROM 兩個子句(clause) 。
SELECT 子句中列舉了希望從表中查詢出的列的名稱,而 FROM 子句 則指定了選取出數據的表的名稱。
注:(1)查詢多列時,需要使用逗號進行分隔
(2) 查詢結果中列的順序和 SELECT 子句中的順序相同 。
(3)想要查詢出全部列時,可以使用代表所有列的星號(*)不過如果使用星號的話,就無法設定列的顯示順序了 。
爲列設定別名
SQL 語句可以使用 AS關鍵字爲列設定別名。
SELECT product_id AS id, product_name AS name, purchase_price AS price
FROM Product;
(1)別名可以使用中文,使用中文時需要用雙引號(")括起來 。
注:使用雙引號可以設定包含空格 (空白)的別名。但是如果忘記使用雙引號就可能出錯,因此並不推薦。
大家可以像product_ id這樣使用下劃線(_)來代替空白。
(2)在SQL語句中使用字符串或者日期常數時,必須使用單引號(')將其括起來。
常數的查詢
SELECT 子句中可以書寫列名,書寫常數,還可以書寫表達式(後面有詳情)。
過濾表中重複數據
使用DISTINCT過濾product_type列中重複的數據
SELECT DISTINCT product_type
FROM Product;
注:在使用DISTINCT 時,NULL 也被視爲一類數據。NULL 存在於多行中時,也會被合併爲一條 NULL 數據。
在多列之前使用DISTINCT
SELECT DISTINCT product_type, regist_date
FROM Product;
DISTINCT 關鍵字只能用在第一個列名之前
根據WHERE語句來選擇記錄
語句通過WHERE 子句來指定查詢數據的條件
SELECT語句中的WHERE子句
SELECT <列名>, ……
FROM <表名>
WHERE <條件表達式>;
執行過程:首先通過 WHERE 子句查詢出符合指定條件的記錄(即:行),然後再選取出SELECT 語句指定的列。
注:
(1)SQL中子句的書寫順序是固定的,不能隨意更改。
(2)WHERE子句也可以使用表達式。
註釋的書寫方法
註釋是SQL 語句中用來標識 說明或者注意事項的部分。
寫法:
● 1行註釋 書寫在“--”之後,只能寫在同一行。
● 多行註釋 書寫在“/*”和“*/”之間,可以跨多行。
註釋能夠幫助閱讀者更好地理解SQL 語句,特別是在書寫複雜的SQL 語句時, 希望大家能夠儘量多加簡明易懂的註釋。
算術運算符和比較運算符
算術運算符
含義 | 運算符 |
---|---|
加法運算 | + |
減法運算 | - |
乘法運算 | * |
除法運算 | / |
SELECT 子句中書寫算術表達式
SELECT product_name, sale_price, sale_price * 2 AS "sale_price_x2"
FROM Product;
SELECT子句中可以使用常數或者表達式。
注:SQL 中也可以像平常的運算表達式那樣使用括號( )。括號中 運算表達式的優先級會得到提升,優先進行運算。
需要注意NULL
A 5 + NULL B 10 - NULL
C 1 * NULL D 4 / NULL
E NULL / 9 F NULL / 0
實際上所有包含 NULL 的計算,結果肯定是 NULL,NULL / 0也不例外。
比較運算符
運算符 | 含義 |
---|---|
= | 和~相等 |
<> | 和~不相等 |
>= | 大於等於~ |
> | 大於~ |
<= | 小於等於~ |
< | 小於~ |
--例:選取出銷售單價大於等於1000日元的記錄
SELECT product_name, product_type, sale_price
FROM Product
WHERE sale_price >= 1000;
注:
(1)小於某個日期就是在該日期之前的意思
(2)使用比較運算符時一定要注意不等號和等號的位置。
WHERE子句的條件表達式中也可以使用計算表達式
--例:
SELECT product_name, sale_price, purchase_price
FROM Product
WHERE sale_price - purchase_price >= 500;
對字符串使用不等號時的注意事項
--例:選取出大於'2'的數據的SELECT語句
SELECT chr
FROM Chars
WHERE chr > '2';
注: 2 和'2' 並 不一樣。
chr 列被定爲字符串類型,並且在對字符串類型的數據進行大小比較時,使用的是和數字比較不同的規則。
字符串類型的數據比較規則即:以相同字符開頭的單詞比不同字符開頭的單詞更相近,與字典順序類似。
'10' 和'11' 同樣都是以'1' 開頭的字符串,首先判定爲比'2' 小。
不能對NULL使用比較運算符
--例:選取出進貨單價不是2800日元的記錄
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price <> 2800;
這兩條記錄由於進貨單價 不明(NULL),因此無法判定是不是 2800日元。
--例:錯誤的SELECT語句(一條記錄也取不出來)
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price = NULL;
使用=運算符也還是無法選取出NULL 的記錄
SQL 提供了專門用來判斷是否爲 NULL 的IS NULL 運算符。
--例:選取NULL的記錄
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
反之,希望選取不是NULL 的記錄時,需要使用 IS NOT NULL 運 算符
邏輯運算符
NOT運算符
NOT運算符用來否定某一條件,但是不能濫用。
--例:選取出銷售單價大於等於1000日元的記錄
SELECT product_name, product_type, sale_price
FROM Product
WHERE NOT sale_price < 1000;
--例:結果與上例一致
SELECT product_name, product_type, sale_price
FROM Product
WHERE sale_price >= 1000;
AND運算符和OR運算符
AND 運算符在其兩側的查詢條件都成立時整個查詢條件才成立,其意思相當於“並且”。
OR 運算符在其兩側的查詢條件有一個成立時整個查詢條件都成立, 其意思相當於“或者”
注:AND 運算符優先於 OR 運算符,想要優先執行OR運算符時可以使用括號。
--例:在WHERE子句的查詢條件中使用OR運算符
SELECT product_name, purchase_price
FROM Product
WHERE product_type = '廚房用具' OR sale_price >= 3000;
通過括號強化處理
--例:通過使用括號讓OR運算符先於AND運算符執行
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '辦公用品' AND ( regist_date = '2009-09-11' OR regist_date = '2009-09-20');
邏輯運算符和真值
NOT、AND 和 OR 稱爲邏輯運算符。這裏所說的邏輯就是對真值進行操作的意思。
真值就是值爲真(TRUE)或假 (FALSE)其中之一的值
AND 運算符兩側的真值都爲真時返回真,除此之外都返回假。
OR 運算符兩側的真值只要有一個不爲假就返回真,只有當其兩側的真值都爲假時才返回假。
NOT 運算符只是單純的將真轉換爲假,將假轉換爲真。
含有NULL時的真值
既不是真也不是假,這時真值是除真假之外的第三種值——不確定(UNKNOWN)
與通常的邏輯運算被稱爲二值邏輯相對,只有 SQL 中 的邏輯運算被稱爲三值邏輯。
考慮到使用NULL 時的條件判斷會變得異常複雜。因此,數據庫領域的有識之士們達成了“儘量不使用 NULL”的共識。
2.聚合與排序
(1)對錶進行聚合查詢
通過 SQL 對數據進行某種操作或計算時需要使用函數
5個常用的函數:
COUNT: 計算表中的記錄數(行數)
SUM: 計算表中數值列中數據的合計值
AVG: 計算表中數值列中數據的平均值
MAX: 求出表中任意列中數據的最大值
MIN: 求出表中任意列中數據的最小值
用於彙總的函數稱爲聚合函數或者聚集函數。
所謂聚合,就是將多行彙總爲一行。實際上,所有的聚合函數都是這樣,輸入多行輸出一行。
計算表中數據的行數(COUNT)
用COUNT 函數時,輸入表的列,就能夠輸出數據行數。
--語法:
SELECT COUNT(parameter)
FROM 表名;
--計算全部數據的行數
SELECT COUNT(*)
FROM Product;
--計算NULL之外的數據行數
SELECT COUNT(具體字段名)
FROM Product;
COUNT函數的結果根據參數的不同而不同。如:COUNT(*)會得到包含NULL的數據的行數,而COUNT(<列名>)會得到NULL之外的數據行數。
注: COUNT 函數使用*代替所有列,其他函數並不能將星號作爲參數。
計算合計值(SUM)
語法與COUNT函數基本相同
聚合函數會將NULL排除在外。但COUNT(*)例外,並不會排除NULL。
--計算分別slae_price與purchase_price的合值
SELECT SUM(sale_price), SUM(purchase_price)
FROM Product;
注:所有的聚合函數,如果以列名爲參數,那麼在計算之前就已經把 NULL 排除在外了。因此,無論有多少個 NULL 都會被無視。這與“等 價爲 0”並不相同 。
計算平均值
其語法和 SUM函數完全相同
不會計算值爲的NULL行
--計算sale_price列的平均值
SELECT AVG(sale_price)
FROM Product;
計算最大值和最小值(MAX&MIN)
這兩個函數的語法與 SUM 的語法相同
但是,MAX/MIN 函數和SUM/AVG函數有一點不同,那就是 SUM/ AVG函數只能對數值類型的列使用,而 MAX/MIN 函數原則上可以適用 於任何數據類型(能夠排序)的列。
使用聚合函數過濾重複值(DISTINCT)
--計算去除重複數據後的數據行數
SELECT COUNT(DISTINCT product_type)
FROM Product;
--先計算數據行數再刪除重複數據的結果
SELECT DISTINCT COUNT(product_type)
FROM Product;
--兩者結果不一致
對錶進行分組
GROUP BY子句
--語法
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……;
GROUP BY 子句就像切蛋糕那樣將表進行分組
在 GROUP BY 子句中指定的列稱爲聚合鍵或者分組列。
子句的書寫順序(暫定) 1. SELECT → 2. FROM → 3. WHERE → 4. GROUP BY
聚合鍵中包含NULL的情況
--按照進貨單價統計數據行數
SELECT purchase_price, COUNT(*)
FROM Product
GROUP BY purchase_price;
聚合鍵中包含NULL時,在結果中會以“不確定”行(空行)的形式表現出來。
使用WHERE子句時GROUP BY的執行結果
-- 語法:使用WHERE子句和GROUP BY子句進行彙總處理
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
WHERE
GROUP BY <列名1>, <列名2>, <列名3>, ……;
執行順序:會先根據 WHERE 子句指定的條件進行過濾,然後再進行彙總處理。
即:GROUP BY 和 WHERE 並用時 SELECT 語句的執行順序 FROM → WHERE → GROUP BY → SELECT
--例:
SELECT purchase_price, COUNT(*)
FROM Product
WHERE product_type = '衣服'
GROUP BY purchase_price;
與聚合函數和GROUP BY子句有關的常見錯誤
1.把聚合鍵之外的列名書寫在SELECT 子句之中。(只有MySQL認同這種語法)
聚合鍵相對應的、同時存在多個值的列出現在SELECT 子 句中的情況,理論上是不可能的。
使用GROUP BY子句時,SELECT子句中不能出現聚合鍵之外的列名。
2.在GROUP BY子句中寫了列的別名
--錯誤示範
SELECT product_type AS pt, COUNT(*)
FROM Product
GROUP BY pt;
--原因:由SQL語句在DBMS內部的執行順序造成的
在GROUP BY子句中不能使用SELECT子句中定義的別名。
3.GROUP BY子句的結果能排序嗎
GROUP BY子句結果的默認顯示是無序的。
4.在WHERE子句中使用聚合函數
只有 SELECT 子句和 HAVING 子句( ORDER BY 子句)中能夠使用COUNT 等聚合函數。
爲聚合結果指定條件
HAVING子句
由於WHERE 子句只能指定記錄(行)的條件,而不能用來指定組的條件,所以可以使用HAVING子句。
--語法:
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……
HAVING <分組結果對應的條件>
--注:HAVING子句要寫在GROUP BY子句之後。
使用 HAVING 子句時 SELECT 語句書寫順序 SELECT → FROM → WHERE → GROUP BY → HAVING
-- 例1:從按照商品種類進行分組後的結果中,取出“包含的數據行數爲2 行”的組
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING COUNT(*) = 2;
--例2:使用HAVING子句設定條件的情況
SELECT product_type, AVG(sale_price)
FROM Product
GROUP BY product_type
HAVING AVG(sale_price) >= 2500;
HAVING 子句中 能夠使用的3種要素如下所示:
● 常數
● 聚合函數
● GROUP BY子句中指定的列名(即聚合鍵)
WHERE子句與HAVING子句
WHERE 子句 = 指定行所對應的條件
HAVING 子句 = 指定組所對應的條件
對查詢結果進行排序
ORDER BY子句
通過在 SELECT 語句末尾添加 ORDER BY 子句來明確指定排列順序。
--語法:
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
ORDER BY <排序基準列1>, <排序基準列2>, ……
--ORDER BY子句中書寫的列名稱爲排序鍵。
子句的書寫順序
1. SELECT 子句 → 2. FROM 子句 → 3. WHERE 子句 → 4. GROUP BY 子句 → 5. HAVING 子句 → 6. ORDER BY 子句注:不論何種情況,ORDER BY 子句都需要寫在 SELECT 語句的末尾。
指定升序或降序
在OPDER BY子句的列名後面使用 DESC(降序)ASC(默認升序) 關鍵字。
--按照銷售單價由高到低(降序)進行排列
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price DESC;
注:由於 ASC 和 DESC 這兩個關鍵字是以列爲單位指定的,因此可以 同時指定一個列爲升序,指定其他列爲降序。
指定多個排序鍵
如果想要對該順序的商品進行更細緻的排序的話,就需要再添加一個 排序鍵。
--按照銷售單價和商品編號的升序進行排序
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price, product_id;
規則是優先使用左側的鍵,如果該列存在相同值的話,再接着參考右側的鍵。當然,也可以同時使用 3個以上的排序鍵。
NULL的順序
使用含有 NULL 的列作爲排序鍵時, NULL 會在結果的開頭或末尾彙總顯示
--按照進貨單價的升序進行排列
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY purchase_price;
在排序鍵中使用顯示用的別名
在 GROUP BY子句中不能使用 SELECT子句中定義的別名,但是在 ORDER BY子句中卻是允許使用名的。
--ORDER BY子句中可以使用列的別名
SELECT product_id AS id, product_name, sale_price AS sp, purchase _price
ROM Product
ORDER BY sp, id;
使用 HAVING 子句時 SELECT 語句的順序
FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY
ORDER BY子句中可以使用的列
ORDER BY 子句中也可以使用存在於表中、但並不包含在 SELECT 子句之中的列
--例:SELECT子句中未包含的列也可以在ORDER BY子句中使用
SELECT product_name, sale_price, purchase_price
FROM Product
ORDER BY product_id;
ORDER BY子句中可以使用列的編號 (不推薦)
-- 通過列名指定
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price DESC, product_id;
-- 通過列編號指定
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY 3 DESC, 1;