
1. 針對相同的表進行的連接
1.1. 相同的表的自連接和不同表間的普通連接并沒有什么區別,自連接里的“自”這個詞也沒有太大的意義
1.2. 與多表之間進行的普通連接相比,自連接的性能開銷更大
-
1.2.1. 特別是與非等值連接結合使用的時候
-
1.2.2. 用于自連接的列推薦使用主鍵或者在相關列上建立索引
2. 組合
2.1. 有順序的有序對(ordered pair)
2.2. 無順序的無序對(unordered pair)
3. 示例
3.1.

3.2. --用于獲取可重排列的SQL陳述句
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2;
- 3.2.1. 可重排列,所以結果行數9
3.3. --用于獲取排列的SQL陳述句
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2
WHERE P1.name <> P2.name;
- 3.3.1. 排除掉由相同元素構成的對,結果行數為排列6
3.4. --用于獲取組合的SQL陳述句
SELECT P1.name AS name_1, P2.name AS name_2
FROM Products P1, Products P2
WHERE P1.name > P2.name;
- 3.4.1. 只與“字符順序比自己靠前”的商品進行配對,結果行數為組合3
3.5. --用于獲取組合的SQL陳述句:擴展成3列
SELECT P1.name AS name_1, P2.name AS name_2, P3.name AS name_3
FROM Products P1, Products P2, Products P3
WHERE P1.name > P2.name
AND P2.name > P3.name;
3.6. ">”和“<”等比較運算子不僅可以用于比較數值大小,也可以用于比較字串(比如按字典序進行比較)或者日期
4. 洗掉重復行
4.1. 示例
-
4.1.1. --用于洗掉重復行的SQL陳述句(1):使用極值函式
DELETE FROM Products P1 WHERE rowid < ( SELECT MAX(P2.rowid) FROM Products P2 WHERE P1.name = P2. name AND P1.price = P2.price ) ;- 4.1.1.1. Oracle資料庫里的rowid
-
4.1.2. --用于洗掉重復行的SQL陳述句(2):使用非等值連接
DELETE FROM Products P1 WHERE EXISTS ( SELECT * FROM Products P2 WHERE P1.name = P2.name AND P1.price = P2.price AND P1.rowid < P2.rowid );
4.2. 如果從物理表的層面來理解SQL陳述句,抽象度是非常低的
4.3. “表”“視圖”這樣的名稱只反映了不同的存盤方法,而存盤方法并不會影響到SQL陳述句的執行和結果
4.4. 無論表還是視圖,本質上都是集合——集合是SQL能處理的唯一的資料結構
5. 查找區域不一致的列
5.1. 示例
-
5.1.1. --用于查找是同一家人但住址卻不同的記錄的SQL陳述句
SELECT DISTINCT A1.name, A1.address FROM Addresses A1, Addresses A2 WHERE A1.family_id = A2.family_id AND A1.address <> A2.address ; -
5.1.2. --用于查找價格相等但商品名稱不同的記錄的SQL陳述句
SELECT DISTINCT P1.name, P1.price FROM Products P1, Products P2 WHERE P1.price = P2.price AND P1.name <> P2.name; -
5.1.3. 如果改用關聯子查詢,就不需要DISTINCT了
6. 排序
6.1. 示例
-
6.1.1. --排序:使用視窗函式
SELECT name, price, RANK() OVER (ORDER BY price DESC) AS rank_1, DENSE_RANK() OVER (ORDER BY price DESC) AS rank_2 FROM Products;-
6.1.1.1. 在出現相同位次后,rank_1跳過了之后的位次,rank_2沒有跳過,而是連續排序
-
6.1.1.2. 依賴于具體資料庫來實作的方法
-
-
6.1.2. --排序從1開始,如果已出現相同位次,則跳過之后的位次
SELECT P1.name, P1.price, (SELECT COUNT(P2.price) FROM Products P2 WHERE P2.price > P1.price) + 1 AS rank_1 FROM Products P1 ORDER BY rank_1;-
6.1.2.1. 不依賴于具體資料庫來實作的方法
-
6.1.2.2. 去掉標量子查詢后邊的+1,就可以從0開始給商品排序
-
6.1.2.3. 如果修改成COUNT(DISTINCT P2.price),那么存在相同位次的記錄時,就可以不跳過之后的位次,而是連續輸出(相當于DENSE_RANK函式)
-
7. 同心圓狀的遞回集合
7.1. 示例
- 7.1.1.

-
7.1.2. --排序:使用自連接
SELECT P1.name, MAX(P1.price) AS price, COUNT(P2.name) +1 AS rank_1 FROM Products P1 LEFT OUTER JOIN Products P2 ON P1.price < P2.price GROUP BY P1.name ORDER BY rank_1;- 7.1.2.1. 外連接就是這樣一個用于將第1名也存盤在結果里的小技巧
-
7.1.3. --排序:改為內連接
SELECT P1.name, MAX(P1.price) AS price, COUNT(P2.name) +1 AS rank_1 FROM Products P1 INNER JOIN Products P2 ON P1.price < P2.price GROUP BY P1.name ORDER BY rank_1;- 7.1.3.1. 沒有比橘子價格更高的水果,所以它被連接條件P1.price < P2.price排除掉了
-
7.1.4. --不聚合,查看集合的包含關系
SELECT P1.name, P2.name FROM Products P1 LEFT OUTER JOIN Products P2 ON P1.price < P2.price;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/548758.html
標籤:MySQL
上一篇:mysql面試小結
