一、連接查詢
- 基本含義:將兩個以上的表(數據源),連接起來成為一個數據源。
- 基本形式:from 表1 [連接方式] join 表2 [on 連接條件]
- join 為連接查詢關鍵字--必須
- [連接方式] [on 連接條件]為可選性
- 交叉連接: from 表1 [cross] join 表2
- 交叉連接為兩兩橫向連接,假如表1有m條記錄,表2有n條記錄,則交叉連接后有m*n條記錄
- 示例:
內連接: from 表1 [inner] join 表2 on 連接條件;在交叉連接基礎上,選取符合on 連接條件的記錄
- on 連接條件 為內連接必選項
- 示例:
- 左外連接:from 表1 left [outer] join 表2 on 連接條件;內連接基礎上,加上表1中不符合條件的記錄(右側部分全為null)
- 示例:
- 示例:
- 右外連接:from 表1 right [outer] join 表2 on 連接條件;內連接基礎上,加上表2中不符合條件的記錄(右側部分全為null)
- 示例:
- 示例:
- 在時間應用中,交叉連接結果並不是都具有實際意義,更過使用的是內連接,舉例:
- 表1:商品信息表(production)
mysql> select * from production; +--------+-----------------------------------+------+-------+-------+--------+ | pro_id | name | type | price | brand | origin | +--------+-----------------------------------+------+-------+-------+--------+ | 1 | 康佳(KONKA)42英寸全高清液晶電視 | 1 | 1999 | 康佳 | 深圳 | | 2 | 索尼(SONY)4G手機(黑色) | 2 | 3238 | 索尼 | 深圳 | | 3 | 海信(Hisense)55英寸智能電視 | 1 | 4199 | 海信 | 青島 | | 4 | 聯想(Lenovo)14.0英寸筆記本電腦 | 3 | 5499 | 聯想 | 北京 | | 5 | 索尼(SONY)13.3英寸觸控超極本 | 3 | 11499 | 索尼 | 天津 | | 6 | 索尼(SONY)60英寸全高清液晶電視 | 1 | 6999 | 索尼 | 北京 | | 7 | 聯想(Lenovo)12.0英寸筆記本電腦 | 3 | 2999 | 聯想 | 北京 | | 8 | 聯想 雙卡雙待3G手機 | 2 | 988 | 聯想 | 北京 | | 9 | 惠普(HP)黑白激光打印機 | 3 | 1169 | 惠普 | 天津 | +--------+-----------------------------------+------+-------+-------+--------+ 9 rows in set (0.01 sec)
- 表2:商品類型表(product_type)
mysql> select * from product_type; +------------+--------------+ | protype_id | protype_name | +------------+--------------+ | 1 | 家用電器 | | 2 | 手機數碼 | | 3 | 電腦辦公 | | 4 | 圖書音像 | | 5 | 家居家具 | | 6 | 服飾配飾 | | 7 | 個護化妝 | | 8 | 運動戶外 | | 9 | 汽車用品 | | 10 | 食品酒水 | | 11 | 營養保健 | +------------+--------------+ 11 rows in set (0.01 sec)
- 請給出索尼 4G手機所屬商品類型名稱:
-
mysql> select protype_name from production as p1 join product_type as p2 on p1.type=p2.protype_id wh ere p1.name like '%SONY%'and p1.name like '%4G%'; +--------------+ | protype_name | +--------------+ | 手機數碼 | +--------------+ 1 row in set (0.00 sec)
-
- 表1:商品信息表(production)
二、子查詢
- 基本含義
- 一般一個查詢,就出現一次select 語句,但如果又出現select 語句,此時就稱后者為‘子查詢’,前者為‘主查詢’
- 形式
- select 字段或者表達式或者(子查詢1) [as 別名] from 表名或者(子查詢2) where 字段或者表達式或者子(查詢3)
- 通常每個位置的子查詢,應該符合該位置的數據需求
- 子查詢1 應該是一個‘數據結果’
- 子查詢2 可以是‘任意結果’
- 子查詢3 可以是一個數據或者一列數據
- 按結果分類
- 表子查詢:子查詢結果為‘多行多列’,通常可以當做‘表’放在from 后面使用
- 行子查詢:子查詢結果為‘一行多列’,通常可以當做‘行’來使用,放在‘行比較語法’
- 列子查詢:子查詢結果為‘多行一列’,通常可以當做‘多個值’來使用,類似(1,3,33,66)
- 標量子查詢:子查詢結果為‘一行一列’,通常可以當做‘一個值’來使用,當做字段使用
- 常見子查詢及相關關鍵字
- 比較運算符中使用子查詢
- 形式: 操作數 比較運算符 (標量子查詢);操作數通常為一個字段
- 含義:判斷操作數(字段)的值是否滿足比較運算符所設定的結果
- 舉例:表
mysql> select * from production; +--------+-----------------------------------+------+-------+-------+--------+ | pro_id | name | type | price | brand | origin | +--------+-----------------------------------+------+-------+-------+--------+ | 1 | 康佳(KONKA)42英寸全高清液晶電視 | 1 | 1999 | 康佳 | 深圳 | | 2 | 索尼(SONY)4G手機(黑色) | 2 | 3238 | 索尼 | 深圳 | | 3 | 海信(Hisense)55英寸智能電視 | 1 | 4199 | 海信 | 青島 | | 4 | 聯想(Lenovo)14.0英寸筆記本電腦 | 3 | 5499 | 聯想 | 北京 | | 5 | 索尼(SONY)13.3英寸觸控超極本 | 3 | 11499 | 索尼 | 天津 | | 6 | 索尼(SONY)60英寸全高清液晶電視 | 1 | 6999 | 索尼 | 北京 | | 7 | 聯想(Lenovo)12.0英寸筆記本電腦 | 3 | 2999 | 聯想 | 北京 | | 8 | 聯想 雙卡雙待3G手機 | 2 | 988 | 聯想 | 北京 | | 9 | 惠普(HP)黑白激光打印機 | 3 | 1169 | 惠普 | 天津 | +--------+-----------------------------------+------+-------+-------+--------+ 9 rows in set (0.00 sec)
- 問題:找出大於平均價的商品
- 第一步:找平均價
-
mysql> select avg(price) from production; +-------------------+ | avg(price) | +-------------------+ | 4287.666666666667 | +-------------------+ 1 row in set (0.00 sec)
-
- 第二步:找商品(大於平均價)
-
mysql> select * from production where price > (select avg(price) from production); +--------+----------------------------------+------+-------+-------+--------+ | pro_id | name | type | price | brand | origin | +--------+----------------------------------+------+-------+-------+--------+ | 4 | 聯想(Lenovo)14.0英寸筆記本電腦 | 3 | 5499 | 聯想 | 北京 | | 5 | 索尼(SONY)13.3英寸觸控超極本 | 3 | 11499 | 索尼 | 天津 | | 6 | 索尼(SONY)60英寸全高清液晶電視 | 1 | 6999 | 索尼 | 北京 | +--------+----------------------------------+------+-------+-------+--------+ 3 rows in set (0.00 sec)
-
- 第一步:找平均價
- 使用in 子查詢
- 形式:where 操作數 in (列子查詢)
- 舉例:問題找出所有帶‘電’字類別的商品
- 第一步:找出帶‘電’字的類別ID
-
mysql> select protype_id from product_type where protype_name like '%電%'; +------------+ | protype_id | +------------+ | 1 | | 3 | +------------+ 2 rows in set (0.00 sec)
-
- 第二步:找商品
-
mysql> select * from production where production.type in (select protype_id from product_type where protype_name like '%電%'); +--------+-----------------------------------+------+-------+-------+--------+ | pro_id | name | type | price | brand | origin | +--------+-----------------------------------+------+-------+-------+--------+ | 1 | 康佳(KONKA)42英寸全高清液晶電視 | 1 | 1999 | 康佳 | 深圳 | | 3 | 海信(Hisense)55英寸智能電視 | 1 | 4199 | 海信 | 青島 | | 4 | 聯想(Lenovo)14.0英寸筆記本電腦 | 3 | 5499 | 聯想 | 北京 | | 5 | 索尼(SONY)13.3英寸觸控超極本 | 3 | 11499 | 索尼 | 天津 | | 6 | 索尼(SONY)60英寸全高清液晶電視 | 1 | 6999 | 索尼 | 北京 | | 7 | 聯想(Lenovo)12.0英寸筆記本電腦 | 3 | 2999 | 聯想 | 北京 | | 9 | 惠普(HP)黑白激光打印機 | 3 | 1169 | 惠普 | 天津 | +--------+-----------------------------------+------+-------+-------+--------+ 7 rows in set (0.00 sec)
-
- 第一步:找出帶‘電’字的類別ID
- 使用any 子查詢
- 形式:where 操作數 比較運算符 any(列子查詢)
- 含義:該操作數的值只要跟列子查詢其中的任意一個值滿足給定的比較運算,就算滿足條件
- 舉例:問題找出所有帶‘電’字類別的商品
mysql> select * from production where production.type = any(select protype_id from product_type wher e -> protype_name like '%電%'); +--------+-----------------------------------+------+-------+-------+--------+ | pro_id | name | type | price | brand | origin | +--------+-----------------------------------+------+-------+-------+--------+ | 1 | 康佳(KONKA)42英寸全高清液晶電視 | 1 | 1999 | 康佳 | 深圳 | | 3 | 海信(Hisense)55英寸智能電視 | 1 | 4199 | 海信 | 青島 | | 4 | 聯想(Lenovo)14.0英寸筆記本電腦 | 3 | 5499 | 聯想 | 北京 | | 5 | 索尼(SONY)13.3英寸觸控超極本 | 3 | 11499 | 索尼 | 天津 | | 6 | 索尼(SONY)60英寸全高清液晶電視 | 1 | 6999 | 索尼 | 北京 | | 7 | 聯想(Lenovo)12.0英寸筆記本電腦 | 3 | 2999 | 聯想 | 北京 | | 9 | 惠普(HP)黑白激光打印機 | 3 | 1169 | 惠普 | 天津 | +--------+-----------------------------------+------+-------+-------+--------+ 7 rows in set (0.00 sec)
- all 子查詢
- 形式:where 操作數 比較運算符 all(列子查詢)
- 含義:該操作數的值必須跟列子查詢其中的所有值滿足給定的比較運算,才算滿足條件
- 舉例:找出價格最高的產品
- 思路一:找出價格大於等於所有價格的商品
mysql> select * from production where price >= all(select price from production); +--------+--------------------------------+------+-------+-------+--------+ | pro_id | name | type | price | brand | origin | +--------+--------------------------------+------+-------+-------+--------+ | 5 | 索尼(SONY)13.3英寸觸控超極本 | 3 | 11499 | 索尼 | 天津 | +--------+--------------------------------+------+-------+-------+--------+ 1 row in set (0.00 sec)
- 思路二:找出最大的價格,對比最大價格找出對應的商品 上文中有提及不在重復
- 思路一:找出價格大於等於所有價格的商品
- some 子查詢
- some 是 any 的同義詞,用法相同
- exists 和 not exists 子查詢
- 形式:where exist (子查詢)
- 含義:如果該子查詢有結果數據(無論什么數據,只要大於等於1行),則就為true,否則就為false
- 舉例:找出具有在售商品的類別信息
mysql> select * from product_type where exists(select * from production as p1 where p1.type = produc t_type.protype_id); +------------+--------------+ | protype_id | protype_name | +------------+--------------+ | 1 | 家用電器 | | 2 | 手機數碼 | | 3 | 電腦辦公 | +------------+--------------+ 3 rows in set (0.00 sec)
- 舉例:找出具有沒有在售商品的類別信息
mysql> select * from product_type where not exists(select * from production as p1 where p1.type = pr oduct_type.protype_id); +------------+--------------+ | protype_id | protype_name | +------------+--------------+ | 4 | 圖書音像 | | 5 | 家居家具 | | 6 | 服飾配飾 | | 7 | 個護化妝 | | 8 | 運動戶外 | | 9 | 汽車用品 | | 10 | 食品酒水 | | 11 | 營養保健 | +------------+--------------+ 8 rows in set (0.00 sec)
- 實際上,這種exists 子查詢,如果涉及2個表(或以上),其內部其實會自動進行“連接查詢”,且其邏輯過程較為復雜,而且不明確,通常認為效率較低,盡量少用
- 比較運算符中使用子查詢
三、聯合查詢
- 形式:select 語句1 union select 語句2
- 基本含義:將2個select 語句查詢的結果“層疊”為一個“大結果”
- 說明:
- 具有相同輸出字段--通常字段類型也相同,具有現實意義
- 結果集中的字段以第一個select 語句的輸出字段為准
- 第一個select 語句的字段可以做別名,單若果做別名,則后續的where,group,order等子句也要用該別名
- 示例:
mysql> (select * from join1) union (select * from join2); +----+------+------+ | id | f1 | f2 | +----+------+------+ | 1 | a1 | b1 | | 2 | a12 | b2 | | 3 | a3 | b3 | | 11 | a1 | b11 | | 12 | a12 | b12 | | 13 | a13 | b13 | +----+------+------+ 6 rows in set (0.00 sec)