[讀書筆記]《SQL基礎教程》

  《sql基礎教程》這本書裏面講的內容大部分都是幾個主流數據庫(mysql、sql server、oracle)之間的共同點,知識點比較基礎,適合sql入門學習。但對於已經系統學過數據的人來說,我個人認爲可以不用再看了。因爲系統學習過的內容包括了這本書裏的,而且應該更爲深入。
注:代碼中"(" “)” 和 “[” "]"之間的語句表示可省略

一、數據庫和sql
       1、DBMS種類
       2、SQL的種類
       3、創建表或數據庫
       4、刪除表
       5、表定義的更新
二、查詢基礎
       1、普通查詢
       2、註釋
       3、算術運算符
       4、比較運算符
       5、邏輯運算符
三、聚合與排序
       1、聚合函數
       2、分組查詢
       3、指令執行順序
       4、對查詢結果進行排序
四、數據更新
       1、簡單插入
       2、插入多行
       3、從其他表中複製數據
       4、刪除表
       5、普通更新
       6、多行更新
       7、事務
五、複雜查詢
       1、視圖
       2、複雜查詢
六、函數、謂詞、CASE表達式
       1、常用函數
       2、謂詞
       3、CASE表達式
七、集合運算
       1、表的加減法
       2、聯結
八、SQL高級處理
       1、窗口函數
       2、GROUPING運算符


 

一、數據庫和sql

1、DBMS的種類:
  1. 層次數據庫 HDB
  2. 關係數據庫 RDB
  3. 面向對象數據庫 OODB
  4. XML數據庫 XMLDB
  5. 鍵值存儲數據庫 KVS
2、SQL的種類:
  1. 數據定義語句(DDL ) create、drop、alter
  2. 數據操縱語句(DML) select、insert、update、delete
  3. 數據控制語句(DCL) commit、rollback、grant、revoke

SQL語句不區分大小寫

  • 字符串常數、日期常數用單引號括起來
  • 別名用雙引號
String sql1 = "SELECT user_name AS "用戶名" ";
String sql2 = "INSERT INTO user VALUES('用戶名')";

3、創建表或數據庫
  1. 創建數據庫:CREATE DATABASE < DB Name >;
  2. 創建表:CREATE TABLE < 表名 >(
    列名稱1 數據類型,
    列名稱2 數據類型,
    列名稱3 數據類型,

    )
  3. 名稱:
  • 半角英文字母(必須以此爲開頭)
  • 半角數字
  • 下劃線(_)
  1. 刪除表:DROP TABLE< 表名 >;
  2. 表定義的更新
  • 添加 ALTER TABLE < tableName > ADDcolumn < listName>
    (在Oracle和sql server中省略column)
    Oracle中添加多列:ALTER TABLE< tableName> ADD (< listName1>, < listName2>, < listName3> …)
  • 刪除列: ALTER TABLE < tableName> DROP COLUMN < listName>;
    (在Oracle和sql server中省略COLUMN)


二、查詢基礎

1、普通查詢:

SELECT (DISTINCT) p_name (AS) pn, p_type
WHEREp_type = '衣服’
FROM product AS p;

  • DISTINCT:刪除重複列,只能用在第一個列名前
  • AS:爲表/列定義別名,在oracle中省略
2、註釋:
  • 單行註釋: “–”之後
  • 多行註釋 :“/” 和 “/”之間
3、算術運算符

      使用算數運算符(+、-、*、/)時,所有包含NULL的計算,結果都爲NULL

  • 注意:NULL/0 不報錯
          5 + NULL = NULL
4、比較運算符

     =、<>、>=、>、<=、< 的順序不能顛倒

  • 注意:不能對NULL使用,可使用 IS NULL 或者 NOT NULL
5、邏輯運算符
SELECT p_name FROM product
WHERE NOT p_price >= 1000
	AND (register_date = '2019-09-11'
		OR register_date = '2019-09-20');
  • 優先級:AND > 0R
  • 三值邏輯:TRUE、FALSE、UNKNOW(值爲NULL的時候)


三、聚合與排序

1、聚合函數
  1. 常用聚合函數:COUNT、SUM、AVG、MAX、MIN
  • 聚合函數不能寫在WHERE子句中
  • COUNT(*):計算包含NULL在內的列
  • COUNT(<列名>):除了NULL以外的列數
  • AVG = (值的合計) / (值的個數)
  1. DISTINCT:刪除重複列之後再進行計算
SELECT COUNT(DISTINCT p_type)
FROM product;

2、分組查詢
SELECT p_type 
FROM product
GROUP BY p_type
HAVING AVG(s_price) >= 2500;

   使用GROUP BY之後,HAVINGSELECT 中只能包含:常數、聚合函數、聚合鍵

  • WHERE:指定行所對應的條件
  • HAVING:指定組所對應的條件
  • 單獨使用GROUP BY分組是無序的
  • GROUP BY 後面緊跟着的 分組列名/聚合鍵 不能寫別名
3、指令執行順序:

     FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

4、對查詢結果進行排序
SELECT id, name, price 
FROM product
	ORDER BY price 
	 	DESC id;
  • 先排price,若相同再按id排序
  • ORDER BY:按照price的值排序,可使用聚合函數
  • DESC:降序,默認爲升序:ASC


四、數據更新

1、簡單插入
INSERT INTO product VALUES('1', "麪包");
//VALUES後面的值要與數據庫中的字段名一一對應,不可漏寫
INSERT INTO product(name) VALUES("麪包");
//VALUES後面的值只需與product後面的值一一對應即可

2、插入多行
  • INSERT INTO product VALUES(‘1’, ‘A’), (‘2’, ‘B’), (‘3’, DEFAULT);
        DEFAULT:插入默認值
  • 在Oracle中,INSERT INTO p VALUES(…)
                                       INTO p VALUES(…)
                      SELECT * FROM DUAL;
    最後的select語句並沒有任何實際意義,但必須加在沒有參照表的SQL語句後。
3、從其他表中複製數據
INSERT INTO p2(type, sum_price)
	SELECT type, SUM(price)
		FROM product
	GROUP BY type;

4、刪除表
  1. 完全刪除:DROP TABLE <表名>;

  2. 刪除全部數據,保留表結構:

  • DELETE FROM <表名>
  • TRUNCATE <表名>; 速度較快,但是沒有WHERE子句
5、普通更新
UPDATE < tableName >
	SET < listName > = < expression>;

6、多行更新
UPDATE < tableName >
	SET < listName > = < expression>[, < list2> = < expression2>, ...]
		WHERE < condition>;
UPDATE < tableName >
	SET (< listName >, < list2> , ...) = (< expression>, < expression2>, ...)
		WHERE < condition>;

7、事務
  1. 在SQLServer 和 PostagreSQL中:
BEGIN TRANSACTION
INSERT INTO chat VALUES('1');
COMMIT;
  1. 在MySQL中:
START TRANSACTION;
INSERT INTO chat VALUES('1');
COMMIT;
  1. 在Oracle 和 DB2 中:
INSERT INTO chat VALUES('1');
COMMIT;
  1. MySQL 和 SQL Server默認自動提交事務;
  2. Oracle需要自己手動提交事務。
  3. 事務的ACID特性:
  • 原子性 atomicity
  • 一致性 consistency
  • 隔離性 isolation
  • 持久性 durability


五、複雜查詢

1、視圖
  1. 創建視圖
CREATE VIEW p(type, product)
AS
SELECT type, COUNT(*)
	FROM produc
		GROUP BY type;
  1. 刪除視圖
DROP VIEW <viewName>;

2、複雜查詢
  1. 標量子查詢:只能返回一行一列的結果
SELECT price
FROM product
WHERE price > 
	(SELECT AVG(price) 
	FROM p)
  • 注意:使用GROUP BY等可能不止一行一列
  1. 關聯子查詢
SELECT type, name, price
FROM p AS p1
WHERE price > 
	(SELECT AVG(price)
		FROM p AS p2
		WHERE p1.type = p2.type
		GROUP BY type);
  • 結合條件一定寫在子查詢中,因爲子查詢中的別名作用域只在子查詢中,例如:p2的作用域只在括號內


六、函數、謂詞、CASE表達式

1、常用函數
  1. ABS——絕對值
  2. MOD——求餘
  • SQL Server使用%求餘
  1. ROUND——四捨五入
  2. ||——拼接符
  • SQL中使用 ”+“
  • MySQL中使用CONCAT(a,b,c,……)
  1. LENGTH——求字符串長度
  2. LOWER/UPPER——大小寫轉換
  3. REPLACE——字符串替換
  • REPLACE(A, B, C):若A中包含B,則把該部分換成C
    (例如:REPLACE(‘123’, ‘2’, ‘6’):123 => 163
  1. CURRENT-TIMESTAMP——當前日期和時間
  2. CAST——類型轉換
/* 把 '001' 轉換成 整型*/
//SQL Server
SELECT CAST('001' AS INTEGER);

//MySQL
SELECT CAST('001' AS SIGNED INTEGER);

//Oracle
SELECT CAST('001' AS INTEGER) FROM DUAL;
  1. COALESCE——將NULL轉換成其他值
//將NULL轉換成1
SELECT COALESCE(NULL, 1);

//在Oracle中
SELECT COALESCE(NULL, 1) FROM DUAL;

2、謂詞
  1. 謂詞:返回值爲真的函數(TRUE / FALSE /UNKNOW)
  2. LIKE——字符串的部分查詢
SELECT * FROM product
WHERE p_name LIKE "%麪包";
  1. BETWEEN——範圍查詢
SELECT column_name(s)
FROM table_name
WHERE column_name
BETWEEN value1 AND value2
  1. IS NULL / IS NOT NULL——判斷是否爲空
  2. IN(OR的簡便用法)
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
  • 子查詢作爲IN的參數
// 查詢價格小於等於100的產品名稱
SELECT p_name
FROM product
WHERE p_name IN (
	SELECT p_price
		FROM product
			WHERE p_price <= 100
);
  1. EXIT——與IN作用相反,查詢不存在條件中的記錄
//查詢價格不在100以內的產品名稱
SELECT p_name
FROM product
WHERE p_name EXIT (
	SELECT p_price
		FROM product
			WHERE p_price <= 100
);

3、CASE表達式

1.簡單表達式

SELECT 
	NAME,
	AGE,
	(CASE AGE
		WHEN '18' THEN '成年'
		ELSE '未成年' END
	 ) AS 是否成年
FROM STUDENT

查詢前:

NAME AGE
zhang 10
xu 18
wang 19

查詢結果:

NAME AGE 是否成年
zhang 10 未成年
xu 18 成年
wang 19 未成年
  • 注意條件,只有18纔是成年
  1. 搜索表達式
SELECT 
	NAME,
	AGE,
	(CASE 
		WHEN AGE>'18' THEN '成年'
		ELSE '未成年' END
	 ) AS 是否成年
FROM STUDENT
  1. 在ORDER BY、GROUP BY 中使用CASE表達式
SELECT (CASE WHEN AGE>18 THEN '已成年'
			ELSE '未成年' END
		) AS 是否成年,
		COUNT(ID) AS 人數	
FROM STUDENT
GROUP BY (CASE WHEN AGE>18 THEN '已成年'
			  ELSE '未成年' END
		) 
ORDER BY (CASE WHEN AGE>18 THEN '已成年'
			  ELSE '未成年' END
		) DESC
  1. 在update中使用CASE表達式
UPDATE STUDENT
SET AGE=(CASE NAME WHEN '毛喜' THEN '19'
			WHEN '李明' THEN '17'
			ELSE AGE END)


七、集合運算

p1:

id name
1 zhang
2 wang
3 xu
4 yan

p2:

id name
1 zhang
5 yuan
6 hong

p3:

id age
1 19
2 17
3 18
4 19
5 18
6 20
1、表的加減法
  1. UNION——表的加法,並集
SELECT id, name FROM p1
UNION [ALL]
SELECT id, name FROM p2
[ORDER BY id];
id name
1 zhang
2 wang
3 xu
4 yan
1 zhang
5 yuan
6 hong
  • ALL:保留重複行,默認爲不選取重複行
  • 兩個SELECT語句後的列數和類型必須相同
  • ORDER BY 只在最後使用一次即可
  1. INTRESECT——選取表中公共部分
SELECT id FROM p1
INTERSECT [ALL]
SELECT id FROM p2;
id name
1 zhang
  1. EXCEPT——記錄的減法
SELECT id FROM p1
EXCEPT 
SELECT id FROM p2
id name
2 wang
3 xu
4 yan
  • 在Oracle中,要將EXCEPT改成MINUS
2、聯結
  1. INNER JOIN——內聯結(與JOIN相同)
SELECT name
FROM p1
INNER JOIN p3
ON p1.id = p3.id;
id name age
1 zhang 19
2 wang 17
3 xu 18
4 yan 19
  1. OUTER JOIN——外聯結
  • LEFT OUTER JOIN
SELECT * FROM p1
LEFT OUTER JOIN p2
ON p1.id = p2.id

LEFT左側的表爲主表(p1),產生p1的完全集,而p2表中匹配的則有值,沒有匹配的則以null值取代。

id name id name
1 zhang 1 zhang
2 wang null null
3 xu null null
4 yan null null
  • RIGHT OUTER JOIN
SELECT * FROM p1
RIGHT OUTER JOIN p2
ON p1.id = p2.id

RIGHT側的表爲主表(p2),產生p2的完全集,而p1表中匹配的則有值,沒有匹配的則以null值取代。

id name id name
1 zhang 1 zhang
5 yuan null null
6 hong null null
  • FULL OUTER JOIN
SELECT * FROM p1
RIGHT OUTER JOIN p2
ON p1.id = p2.id

產生p1和p2的並集。對於沒有匹配的記錄,則會以null做爲值。

id name id name
1 zhang 1 zhang
2 wang null null
3 xu null null
4 yan null null
null null 5 yuan
null null 6 hong
  1. CROSS JOIN——交叉聯結(笛卡爾積)
SELECT * FROM p1
CROSS JOIN p2

把表p1和表p2的數據進行一個NM的組合,即笛卡爾積。如本例會產生43=12條記錄(很少用)。

  1. 三張以上表的聯結
SELECT sp.shop_id, sp.shop_name, sp.p_id, p.p_name
FROM shop_product AS sp
INNER JOIN product AS p
ON sp.p_id = p.p_id
	INNER JOIN inven_product AS ip
		ON sp.p_id = ip.p_id
WHERE ip.i_id = 'poo1';


八、SQL高級處理

1、窗口函數
<窗口函數> OVER ( [PARTITION BY <列清單>]
		ORDER BY <排序用列清單> )
  • 能作爲窗口函數的聚合函數:SUM、AVG、COUNT、MAX、MIN
  • RANK、DENSE_RANK、ROW_NUMBER……
  • PARITION BY :設定排序的對象範圍
  • ORDER BY :把 排序用列清單 按一定順序標上1,2,3……但整體是亂序的
  1. RANK()函數
SELECT p_name, p_type, s_price
RANK() OVER ( PARITION BY p_type
	ORDER BY s_price ) AS ranking
FROM p 
ORDER BY ranking;
  • 注意:若排序後,存在三條相同的值並列第一,則RANK()、DENSE_RANK()、ROW_NUMBER()排序的結果都不一樣
    RANK():三條相同的結果排名都爲1,第四條爲4
    DENSE_RANK():三條相同的結果排名都爲1,但第四條爲2
    ROW_NUMBER():三條相同的結果一次排序,但序號不同,分別爲1,2,3,第四條爲4
2、GROUPING 運算符
  • GROUPING (< listName>) ,如果listName的值爲NULL則返回1,其他則爲0
  1. ROLLUP——同時得出合計和小計
SELECT p_type, r_date, SUM(s_price) AS sum_price
FROM p
GROUP BY ROLLUP (p_type, r_date);
  • 在MySQL中的語句爲
SELECT p_type, r_date, SUM(s_price) AS sum_price
FROM p
GROUP BY p_type, r_date 
WITH ROLLUP;
  1. CUBE——用數據來搭積木
  2. GROUPING SETS——取得期望的積木
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章