一、簡介
數據庫管理系統(DBMS)最重要的功能就是提供數據查詢,即用戶根據實際需求對數據進行篩選,並以特定形式進行顯示。在Microsoft SQL Serve 2012 中,可以使用通用的SELECT語句進行查詢操作,該語句具有非常靈活的使用方式和豐富的功能,即可以完成簡單的單表查詢,也可以完成復雜的連接查詢和嵌套查詢,本文就將對常用的大多數SQL中的數據查詢語句進行總結和演示;
二、實操部分
本節中使用到的數據是美團的商家信息數據,隸屬於數據庫practice下的表T;
2.1 使用SELECT語句進行查詢
2.1.1 對列查詢
/* 選擇所有列 */ USE practice GO SELECT * FROM T GO
查詢結果:
/* 選擇單個列 */ USE practice GO SELECT 店鋪名稱 FROM T GO
查詢結果:
/* 選擇多個列 */ USE practice GO SELECT 店鋪名稱,商品名稱 FROM T GO
查詢結果:
/* 為選擇的列設置代號 */ USE practice GO SELECT 店鋪名稱 AS Shop_Name,商品名稱 AS Goods_Name FROM T GO
查詢結果:
/* 利用字符查詢表達式連接信息 */ USE practice GO SELECT 店鋪名稱+菜系 AS 店鋪屬性 FROM T GO
查詢結果:
/* 利用算數運算符生成新信息 */ USE practice GO SELECT 價格/原價 AS 折扣 FROM T GO
查詢結果:
2.1.2 去重查詢
/* 查詢某列的去重信息 */ USE practice GO SELECT DISTINCT 菜系 FROM T GO
查詢結果:
2.1.3 限制查詢的行數
/* 查詢前10行數據 */ USE practice GO SELECT TOP 10 * FROM T GO
查詢結果:
/* 查詢前20%行的數據 */ USE practice GO SELECT TOP 20 PERCENT * FROM T GO
查詢結果:
2.2 使用WHERE子句進行條件查詢
2.2.1 使用比較運算符
/* 查詢菜系為火鍋的所有數據 */ USE practice GO SELECT * FROM T WHERE 菜系 = '火鍋' GO
查詢結果:
/* 查詢價格大於等於100的所有數據 */ USE practice GO SELECT * FROM T WHERE 價格 >= 100 GO
查詢結果:
/* 查詢菜系非火鍋的所有數據 */ USE practice GO SELECT * FROM T WHERE 菜系 != '火鍋' GO
查詢結果:
2.2.2 使用邏輯運算符
/* 查詢菜系為火鍋且價格大於100的所有數據 */ USE practice GO SELECT * FROM T WHERE 菜系 = '火鍋' AND 價格 >= 100 GO
查詢結果:
/* 查詢菜系為火鍋或甜品飲品的所有數據 */ USE practice GO SELECT * FROM T WHERE 菜系 = '火鍋' OR 菜系 = '甜點飲品' GO
查詢結果:
/* 查詢菜系不為火鍋的所有數據 */ USE practice GO SELECT * FROM T WHERE NOT 菜系 = '火鍋' GO
查詢結果:
2.2.3 使用LIKE運算符
LIKE是模式匹配運算符,功能類似正則表達式,用於指定一個字符串是否與指定的字符串模式相匹配,使用LIKE運算符的代碼格式如下:
[NOT] LIKE '匹配字符串' [ESCAPE '<轉義字符>']
方括號中的內容是可選的,若一個LIKE關鍵詞前帶有NOT,則代表進行相反的操作(即指匹配未出現匹配字符串的目標);ESCAPE子句用於指定轉義字符。匹配字符串可以是一個完整的字符串,也可以包含通配符% _ [] [^],這四種通配符的含義如下:
通配符 | 含義 |
% | 代表任意長度(長度可以為0)的字符串 |
_ | 代表任意單個字符 |
[] | 指定范圍或集合內的任意單個字符 |
[^] | 不在指定范圍或集合內的任意單個字符 |
下面是通配符的一些示例:
LIKE 'AB%' 返回以AB開頭的任意長字符串
LIKE '%ABC' 返回以ABC結尾的任意長字符串
LIKE '%ABC%' 返回包含ABC的任意長字符串
LIKE '_AB' 返回以AB結尾的長度為3的字符串
LIKE '[ABC]%' 返回以A、B、C任意一個開頭的任意長字符串
LIKE 'L[^A]%' 返回以L開頭,且第二個字符不是A的,任意長字符串
我們在WHERE中使用LIKE子句來進行字符串的模式匹配:
/* 查詢所有連鎖店(即名稱里帶有中文括號) */ USE practice GO SELECT 店鋪名稱 FROM T WHERE 店鋪名稱 LIKE '%(%' GO
查詢結果:
/* 查詢所有川菜店 */ USE practice GO SELECT 店鋪名稱+' '+菜系 AS 川菜店 FROM T WHERE 菜系 LIKE '川_' GO
查詢結果:
/* 查詢所有連鎖店(即店鋪名稱以')'結尾) */ USE practice GO SELECT 店鋪名稱 FROM T WHERE 店鋪名稱 LIKE '%[)]' GO
查詢結果:
/* 查詢所有非連鎖店(即店鋪名稱不以')'結尾) */ USE practice GO SELECT 店鋪名稱 FROM T WHERE 店鋪名稱 LIKE '%[^)]' GO
查詢結果:
2.2.4 使用BETWEEN...AND...運算符
運算符BETWEEN...AND...和NOT BETWEEN...AND...可以用來查找列的值在或不在指定的范圍內。其中BETWEEN后是范圍的下限(包括下限),AND后是范圍的上限(包括上限)。
/* 查詢所有價格在100到200之間的商品名稱及對應價格 */ USE practice GO SELECT 商品名稱,價格 FROM T WHERE 價格 BETWEEN 100 AND 200 GO
查詢結果:
/* 查詢所有價格不在100到200之間的商品名稱及對應價格 */ USE practice GO SELECT 商品名稱,價格 FROM T WHERE 價格 NOT BETWEEN 100 AND 200 GO
查詢結果:
2.2.5 使用IN運算符
IN運算符可以用來表示列的值屬於或不屬於指定的集合。如果值屬於制定的集合,返回true,否則返回false;
/* 查詢所有菜系在('火鍋','燒烤烤肉','小吃快餐')中的店鋪的名稱及所屬菜系 */ USE practice GO SELECT 店鋪名稱,菜系 FROM T WHERE 菜系 IN('火鍋','燒烤烤肉','小吃快餐') GO
查詢結果:
/* 查詢所有菜系不在('火鍋','燒烤烤肉','小吃快餐')中的店鋪的名稱及所屬菜系 */ USE practice GO SELECT 店鋪名稱,菜系 FROM T WHERE 菜系 NOT IN('火鍋','燒烤烤肉','小吃快餐') GO
查詢結果:
2.2.6 使用IS NULL運算符
運算符IS NULL可以判斷列的值是否是NULL。如果是則返回true,否則返回false;
USE practice GO -- 插入一行帶有空值的樣本 INSERT INTO T VALUES(NULL,NULL,NULL,NULL,'川菜',100,230,'重慶') -- 查找商品名稱為NULL的樣本 SELECT * FROM T WHERE 商品名稱 IS NULL GO
查詢結果:
2.3 排序查詢
使用ORDER BY子句可以按一個或多個屬性列對數據進行排序。ORDER BY子句通常位於WHERE子句后面,默認的排序方式有兩種(升序和降序),通過關鍵字ASC和DESC來指定。其中,ASC表示升序,DESC表示降序,默認為升序即ASC。當排序列包含空值NULL時,若使用ASC關鍵字,則排序列為空值的記錄放在最后,若使用DESC關鍵字,則排序列為空值的記錄放在最前,即默認NULL是最大的數值;
/* 以價格列為排序列進行整體的降序排序 */ USE practice GO SELECT * FROM T ORDER BY 價格 DESC GO
查詢結果:
/* 以價格列為排序列進行商品屬性的升序排序 */ USE practice GO SELECT 店鋪名稱+' '+商品名稱 AS 商品,價格 FROM T ORDER BY 價格 GO
查詢結果:
/* 以 價格列-店鋪名稱列 為主次排序列進行商品屬性的升序排序 */ USE practice GO SELECT 店鋪名稱+' '+商品名稱 AS 商品,價格 FROM T ORDER BY 價格,店鋪名稱 GO
查詢結果:
2.4 使用聚合函數進行查詢
在SELECT語句中可以加上各種聚合函數進行統計並返回統計結果,可以得到很多有價值的信息;
常見的聚合函數包括COUNT()、SUM()、AVG()、MAX()、MIN()。
——計數函數:COUNT([DISTINCT or ALL] 列名稱 or *)
——求和函數:SUM([DISTINCT or ALL] 列名稱)
——求平均值函數:AVG([DISTINCT or ALL] 列名稱)
——求最大值函數:MAX([DISTINCT or ALL] 列名稱)
——求最小值函數:MIN([DISTINCT or ALL] 列名稱)
其中,DISTINCT短語控制在計算時取消指定列中的重復值,即只處理唯一值;而ALL則控制計算時不取消指定列中的重復值,默認為ALL;下面以一系列的例子來演示各聚合函數:
/* 計算表中菜系這一列不去重的情況下元素個數 */ USE practice GO SELECT COUNT(菜系) AS 元素個數 FROM T GO
查詢結果:
/* 計算表中菜系這一列不去重的情況下元素個數 */ USE practice GO SELECT COUNT(DISTINCT 菜系) AS 菜系數量 FROM T GO
查詢結果:
/* 計算表中價格這一列最大值與最小值 */ USE practice GO SELECT MAX(價格) AS 最高價格,MIN(價格) AS 最小價格 FROM T GO
查詢結果:
/* 計算表中價格這一列平均值與求和值 */ USE practice GO SELECT AVG(價格) AS 平均價格,SUM(價格) AS 價格之和 FROM T GO
查詢結果:
2.5 分組查詢
使用GROUP BY子句可以將查詢結果按照某個字段或多個字段進行分組,字段值相等的為一組。這樣做的目的是為了細化聚合函數的作用對象,即,如果未進行分組,則聚合函數將作用於所有對象;若進行分組,則聚合函數將作用於對應的每一個分組;下面是幾個簡單的例子:
/* 以菜系作為分組依據列,查詢各菜系的店鋪數量及對應菜系 */ USE practice GO SELECT COUNT(*) AS 各菜系店鋪數量,菜系 FROM T GROUP BY 菜系 GO
查詢結果:
/* 以菜系作為分組依據列,查詢各菜系的平均商品價格及對應菜系 */ USE practice GO SELECT AVG(價格) AS 各菜系商品平均價格,菜系 FROM T GROUP BY 菜系 GO
查詢結果:
如果分組后需要按照一定的條件對這些組進行篩選,即最終只需要輸出滿足要求的組,則可以在GROUP BY之后指定HAVING語句添加篩選條件:
/* 以菜系作為分組依據列,查詢平均商品價格小於100的菜系及對應的平均商品價格 */ USE practice GO SELECT AVG(價格) AS 各菜系商品平均價格,菜系 FROM T GROUP BY 菜系 HAVING AVG(價格) < 100 GO
查詢結果:
*HAVING語句與WHERE語句的區別在於,他們的作用對象不同:WHERE語句作用於基表或視圖,HAVING語句作用於分組,即其對象是分組后的組內對應值。
2.6 嵌套查詢
在SQL語言中,將一個查詢語句嵌套在另一個查詢語句中的查詢稱作嵌套查詢,又稱子查詢,SQL語言允許許多層嵌套查詢,即一個子查詢中還可以嵌套更多層子查詢。在使用子查詢時,注意事項如下:
1.子查詢必須用圓括號括起來;
2.子查詢中應避免使用ORDER BY語句;
3.嵌套查詢一般的求解方式時由里往外,即每一個子查詢需要在更內層的查詢結束后才會生效,子查詢的結果是外層的父查詢的查找條件。
2.6.1 帶IN的嵌套查詢
在嵌套查詢中,子查詢的結果往往是一個集合,所以IN是嵌套查詢中最常見的謂詞語句,其使用方式為:
WHERE<條件表達式>
IN (子查詢)
/* 利用嵌套查詢選擇商品名稱中帶有WiFi的店鋪名稱與商品名稱,其中子查詢查詢商品名稱滿足要求的 店鋪名稱與商品名稱的集合,父查詢查詢店鋪名稱和商品名稱與子查詢輸出集合相匹配的店鋪名稱及商品名稱*/ USE practice GO SELECT 店鋪名稱,商品名稱 FROM T WHERE 店鋪名稱 IN (SELECT 店鋪名稱 FROM T WHERE 商品名稱 LIKE '%WiFi%') AND 商品名稱 IN (SELECT 商品名稱 FROM T WHERE 商品名稱 LIKE '%WiFi%') GO
查詢結果:
/* 利用嵌套查詢查詢商品名稱中帶有WiFi且價格低於100元的商品對應的店鋪名稱、商品名稱、價格 */ USE practice GO SELECT 店鋪名稱,商品名稱,價格 FROM T WHERE 店鋪名稱 IN -- 第一層子查詢 (SELECT 店鋪名稱 FROM T WHERE 商品名稱 LIKE '%WiFi%' AND 價格 IN -- 第二層子查詢 (SELECT 價格 FROM T WHERE 價格 <= 100)) GO
查詢結果:
2.6.2 帶比較運算符的嵌套查詢
帶有比較運算符的子查詢是指父查詢與子查詢之間用比較運算符進行連接。當用戶能確切知道內層查詢返回的是單值時,可以用=、>、<、>=、<=、!=、或<>等比較運算符,而且通過嵌套查詢,我們可以實現在WHERE語句中使用聚合函數返回的單值,下面是兩個個比較有代表性的例子:
/* 使用嵌套循環查詢所有商品中價格最貴的對應的菜系中所有商品的價格,用來進行比較 */ USE practice GO SELECT 店鋪名稱,商品名稱,價格,菜系 FROM T WHERE 菜系 = (SELECT 菜系 FROM T WHERE 價格 = (SELECT MAX(價格) FROM T)) --使用嵌套查詢便可在WHERE中使用聚合函數返回的值 GO
查詢結果:
/* 使用嵌套循環查詢所有商品中價格小於等於平均價格的對應行的店鋪名稱,商品名稱,價格,菜系 */ USE practice GO SELECT 店鋪名稱,商品名稱,價格,菜系 FROM T WHERE 價格 <= (SELECT AVG(價格) FROM T) --使用嵌套查詢便可在WHERE中使用聚合函數返回的值 GO
查詢結果:
2.6.3 帶ANY或ALL的嵌套查詢
我們前面介紹的嵌套查詢的子查詢局限性在於只能返回單值,我們可以通過結合ANY、ALL,實現子查詢的多值返回查詢。使用ANY或ALL謂詞時,必須同時使用比較運算符,其對應含義如下表:
運算符 | 語義 |
>ANY | 大於子查詢結果中的某個值 |
>ALL | 大於子查詢結果中的所有值 |
<ANY | 小於子查詢結果中的某個值 |
<ALL | 小於子查詢結果中的所有值 |
>=ANY | 大於等於子查詢結果中的某個值 |
>=ALL | 大於等於子查詢結果中的所有值 |
<=ANY | 小於等於子查詢結果中的某個值 |
<=ALL | 小於等於子查詢結果中的所有值 |
=ANY | 等於子查詢結果中的某個值 |
=ALL | 等於子查詢結果中的所有值 |
!= or <>ANY | 不等於子查詢結果中的某個值 |
!= or <>ALL | 不等於子查詢結果中的所有值 |
因為下面的內容經常涉及到多個表,因此介紹一下接下來會使用到的兩個數據表:
table1:美團商戶商品信息表,包含的字段如下(我們利用SQL語句來查看字段名稱):
/* 查看table1的所有字段名 */ USE sample GO SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'table1' GO
查詢結果:
table2:美團商戶商家信息表,包含的字段如下:
/* 查看table2的所有字段名 */ USE sample GO SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'table2' GO
查詢結果:
下面對ANY及ALL的使用進行舉例說明:
/* 查詢table1中本月銷量比table2中本月銷量最大值還高的商品的店鋪名稱與商品名稱 */ USE sample GO SELECT 店鋪名稱,本月銷量 FROM table1 WHERE 本月銷量 > ALL(SELECT 本月銷量 FROM table2) GO
查詢結果:
USE sample GO SELECT * FROM table1 WHERE 本月銷售額 < ANY (SELECT 本月銷售額 FROM table2) GO
查詢結果:
2.6.4 帶EXISTS的嵌套查詢
EXISTS關鍵字后面的參數是一個任意的子查詢。如果子查詢有返回行(至少返回一行),那么EXISTS的結果為true,此時外層查詢語句將執行查詢;如果子查詢沒有返回任何行,那么EXISTS的結果為false,此時外層查詢將不會執行;
/* 以table1中是否有店鋪名稱為海底撈的數據作為判斷依據 */ USE sample GO SELECT * FROM table1 WHERE EXISTS(SELECT * FROM table1 WHERE 店鋪名稱 = '海底撈') GO
查詢結果:
可以看出,因為子查詢沒有查找到“海底撈”的記錄,EXISTS返回false,導致外層的查詢停止,沒有返回任何行的數據
/* 以table1中是否有店鋪名稱為小丸子料理的數據作為判斷依據 */ USE sample GO SELECT * FROM table1 WHERE EXISTS(SELECT * FROM table1 WHERE 店鋪名稱 = '小丸子料理') GO
查詢結果:
這里因為table1中存在小丸子店鋪的記錄:
所以EXISTS返回true,使得外層查詢得以實現
2.7 集合查詢
SELECT查詢語言的結果集往往是一個包含了多行數據(記錄)的集合。而集合之間可以進行並、交、差等運算。在Microsoft SQL Server 2012 中,兩個查詢語句之間也可以進行集合運算,其中主要包括並運算UNION、交運算INTERSECT和差運算EXCEPT。
2.7.1 並運算
在進行並運算時,參與運算的兩個查詢語句,其結果中的列的數量和順序必須相同,且數據類型必須兼容(即字符和數值必不兼容,而數值型與類型更細的比如雙精度浮點數之間兼容)。
默認情況下,UNION運算符將從結果中刪掉重復的行,但可以通過使用UNION ALL運算符保留所有的行。
/* 查詢table1中一口酸牛奶和一只酸奶牛各自六月份的紫米露商品信息並取並集 */ USE sample GO SELECT 商品名稱,店鋪名稱 FROM table1 WHERE 店鋪名稱 LIKE '一口酸牛奶%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名稱 LIKE '%紫米露%' UNION ALL SELECT 商品名稱,店鋪名稱 FROM table1 WHERE 店鋪名稱 LIKE '一只酸奶牛%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名稱 LIKE '%紫米露%' GO
查詢結果:
/* 查詢table1中一口酸牛奶和一只酸奶牛各自六月份的紫米露商品信息並取並集(去除重復項) */ USE sample GO SELECT 商品名稱 FROM table1 WHERE 店鋪名稱 LIKE '一口酸牛奶%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名稱 LIKE '%紫米露%' UNION SELECT 商品名稱 FROM table1 WHERE 店鋪名稱 LIKE '一只酸奶牛%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名稱 LIKE '%紫米露%' GO
查詢結果:
2.7.2 交運算
交運算(INTERSECT)返回兩個查詢語句檢索出來的共有行。
/* 查詢table1中本月銷量在table1中第一且菜系為小吃快餐的店鋪名稱 */ USE sample GO SELECT 店鋪名稱 FROM table1 WHERE 本月銷量 = (SELECT MAX(本月銷量) FROM table1) INTERSECT SELECT 店鋪名稱 FROM table1 WHERE 菜系 = '小吃快餐'
查詢結果:
2.7.3 差操作
差運算(EXCEPT)返回的是第一個查詢語句查詢結果有,但第二個查詢語句的查詢結果中沒有的行。
/* 查詢table1中本月銷量大於平均銷量,但菜系不為火鍋的記錄對應的店鋪名稱、本月銷量、菜系 */ USE sample GO SELECT 店鋪名稱,本月銷量,菜系 FROM table1 WHERE 本月銷量 > (SELECT AVG(本月銷量) FROM table1) EXCEPT SELECT 店鋪名稱,本月銷量,菜系 FROM table1 WHERE 菜系 = '火鍋'
查詢結果:
2.8 連接查詢
在關系型數據庫管理系統中,數據之間往往存在一定的聯系,且分散存儲在不同的數據表中。但是,在實際應用中往往需要同時從兩個或兩個以上的數據表中檢索數據,並且每個表中的數據往往仍以單獨的列出現在結果集中。實現從兩個或兩個以上表中檢索數據且結果集中出現的列來自於兩個或兩個以上表中的檢索操作稱為連接技術。連接查詢是關系型數據庫中非常重要的查詢方式,包括交叉連接、內連接、外連接三種。
連接可以在SELECT語句的FROM子句或WHERE子句中建立,在FROM子句中指出連接時有助於將連接操作與WHERE子句中的搜索條件區別開,因此推薦前者,我在下面的演示中也將使用第一種風格的代碼方式:
在FROM子句中指定連接條件的語法格式為:
SELECT <目標列表達式>
FROM <表1> 連接類型 <表2>
其中連接類型可以是交叉連接(CROSS JOIN)、內連接(INNER JOIN)、外連接(OUTER JOIN);ON子句指定連接條件,它由被連接表中的列和比較運算符、邏輯運算等構成。
*連接可以對同一個表操作,也可以對多個表操作,對同一個表操作的連接稱作自連接
2.8.1 交叉連接查詢
交叉連接又稱笛卡爾積,它返回兩個表中所有數據行的全部組合,即結果集的數據行數等於兩個表的數據行數之積,列為兩個表的屬性列之和。因此交叉連接的結果會產生很多沒用的記錄組合,且相當耗費時間,因此其實際意義不大,其語法格式如下:
SELECT 字段列表 FROM 表1 CROSS JOIN 表2
/* 將table1中的店鋪名稱與table2中的商家地址做交叉連接(注意要注明字段所屬的表) */ USE sample GO SELECT TOP 10000 table1.店鋪名稱,table2.商家地址 FROM table1 CROSS JOIN table2
查詢結果:
可以看出,交叉連接無意義就在於它將第一個表中的m條記錄分別與第二個表中的n條記錄做組合,這就導致非常消耗計算機時間,這里我只選了前1000行做演示,因為這兩個表m x n會到達上億行;
2.8.2 內連接查詢
內連接(INNER JOIN)使用比較運算符比較被連接列的列值,並列出與連接條件相匹配的數據行。根據所使用的比較方式不同,內連接又分為等值連接、非等值連接和自連接。
2.8.2.1 等值與非等值連接查詢
連接查詢中用來連接兩個表的條件稱為連接條件或連接謂詞,它的一般格式如下:
表1.列1 比較運算符 表2.列2
可以使用的比較運算符有:>、>=、<、<=、!=、<>,還可以用VETWEEN...AND...之類的謂詞。當連接運算符為等號(=)時,稱為等值連接。使用其他比較運算符就構成了非等值連接。
/* 將table1中的商品名稱、店鋪名稱與table2中的商家地址做內連接,連接條件為兩個表中記錄商家地址的列相等(等值連接) */ USE sample GO SELECT table1.商品名稱 AS 商品名稱,table1.店鋪名稱 AS 店鋪名稱,table2.商家地址 FROM table1 INNER JOIN table2 ON table1.店鋪名稱 = table2.商家名稱 GO
查詢結果:
/* 將table1中的商品名稱、本與銷售額與table2中的商家名稱、本月銷售額做內連接,連接條件為table1中商品的銷售額比table2中的商家的銷售額還大 */ USE sample GO SELECT TOP 100000 table1.商品名稱, table1.本月銷售額 AS 本月商品銷售額,table2.商家名稱,table2.本月銷售額 AS 本月店家銷售額 FROM table1 INNER JOIN table2 ON table1.本月銷售額 > table2.本月銷售額 GO
查詢結果:
2.8.2.2 自連接查詢
連接不僅可以在不同的之間進行,也可以在同一個表之間進行,這種連接稱為自連接,又因為自連接中進行連接操作的實際上是一樣的表,因此需要在查詢語句中為表起代號:
/* 使用自連接的方式查詢table1中同屬於自助餐的且銷售額為高低關系的所有店鋪的組合 */ USE sample GO SELECT t1.商家名稱,t1.本月銷售額,t2.商家名稱,t2.本月銷售額,t2.菜系 FROM table2 AS t1,table2 AS t2 WHERE t1.菜系 = '自助餐' AND t1.本月銷售額 > t2.本月銷售額 AND t2.菜系 = '自助餐' GO
查詢結果:
2.8.3 外連接查詢
在內連接操作中,只有滿足連接條件的記錄才能作為結果輸出,但有時我們希望看到額外的不滿足條件的數據,這時候可以使用外連接(OUTER JOIN)查詢來實現:
外連接有三種形式:
1.左外連接(LEFT OUTER JOIN)
左外連接的結果集中將包含左邊表的所有記錄(不管右邊的表中是否存在滿足條件的記錄),以及右邊表中滿足連接條件的所有記錄
2.右外連接(RIGHT OUTER JOIN)
與左外連接正好相反
3.全連接(FULL OUTER JOIN)
左外連接與右外連接的並集
/* 使用左外連接的方式查詢在table1和table2中菜系均為自助餐的記錄 */ USE sample GO SELECT TOP 10000 t1.店鋪名稱,t1.本月銷售額,t2.商家名稱,t2.本月銷售額,t2.菜系 FROM table1 AS t1 LEFT OUTER JOIN table2 AS t2 ON t1.菜系 = '自助餐' AND t2.菜系 = '自助餐' GO
查詢結果:
可以看出,因為采取的是左外連接,所以table1中的非自助餐店鋪的名稱也會顯示出來,但因為不匹配連接條件,所以對應的table2中列的屬性為NULL
/* 使用右外連接的方式查詢在table1和table2中菜系均為自助餐的記錄 */ USE sample GO SELECT TOP 10000 t1.店鋪名稱,t1.本月銷售額,t2.商家名稱,t2.本月銷售額,t2.菜系 FROM table1 AS t1 RIGHT OUTER JOIN table2 AS t2 ON t1.菜系 = '自助餐' AND t2.菜系 = '自助餐' GO
查詢結果:
可以看出,這時的效果與左外連接正好相反
以上就是關於SQL server 2012中查詢語句的基本用法,與其他的DBMS大同小異,今后會繼續介紹其它類型的DBMS的相關知識,如有筆誤,望指出。