關於SQL SERVER的表聯接查詢INNER JOIN 、LEFT JOIN和RIGHT JOIN,經常會用到ON和WHERE的條件查詢,以前用的時候有時是憑感覺的,總是沒有搞清楚,今日親自測試了下,理解到了一些內容,在此分享。
要測試,首先我們來創建三張表,數據庫就根據自己的情況而定
創建表TestJoinOnOrWhere_A、TestJoinOnOrWhere_B、TestJoinOnOrWhere_C
/****** Object: Table [dbo].[TestJoinOnOrWhere_A] Script Date: 2015/4/3 14:34:41 ******/ CREATE TABLE [dbo].[TestJoinOnOrWhere_A]( [id] [int] NULL, [value] [int] NULL ) ON [PRIMARY] GO /****** Object: Table [dbo].[TestJoinOnOrWhere_B] Script Date: 2015/4/3 14:34:41 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[TestJoinOnOrWhere_B]( [id] [int] NULL, [value] [int] NULL ) ON [PRIMARY] GO /****** Object: Table [dbo].[TestJoinOnOrWhere_C] Script Date: 2015/4/3 14:34:41 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[TestJoinOnOrWhere_C]( [id] [int] NULL, [value] [int] NULL ) ON [PRIMARY]
表創建好了然后我們添加幾條數據
INSERT [dbo].[TestJoinOnOrWhere_A] ([id], [value]) VALUES (1, 1) INSERT [dbo].[TestJoinOnOrWhere_A] ([id], [value]) VALUES (2, 1) INSERT [dbo].[TestJoinOnOrWhere_A] ([id], [value]) VALUES (3, 2) INSERT [dbo].[TestJoinOnOrWhere_B] ([id], [value]) VALUES (1, 1) INSERT [dbo].[TestJoinOnOrWhere_B] ([id], [value]) VALUES (2, 3) INSERT [dbo].[TestJoinOnOrWhere_B] ([id], [value]) VALUES (3, 4) INSERT [dbo].[TestJoinOnOrWhere_C] ([id], [value]) VALUES (1, 1) INSERT [dbo].[TestJoinOnOrWhere_C] ([id], [value]) VALUES (2, 2) INSERT [dbo].[TestJoinOnOrWhere_C] ([id], [value]) VALUES (3, 3)
現在我們開始測試
語句1:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 語句2:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id
結果1:
id value id value
-------------------------------
1 1 1 1
2 1 2 3
3 2 NULL NULL
結果2
id value id value
-------------------------------
1 1 1 1
2 1 2 3
3 2 3 4
在網上查詢到,有的人說a.value = 1沒有生效,其實不然,它已經生效,只是在左聯接查詢時,左表的數據是不會受影響,只有右表的數據會根據a.value = 1條件取出左表(a表)Value為1的行,通過上面兩個語句的結果就可以看出,那么我們用右表篩選條件會出現什么呢?看看下面語句
語句3:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND b.value = 1
結果3:
id value id value
-------------------------------
1 1 1 1
2 1 NULL NULL
3 2 NULL NULL
以上結果看出,也只是影響了右表的數據
語句4:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.value = 1
結果4:
id value id value
-------------------------------
1 1 1 1
1 1 2 3
1 1 3 4
2 1 1 1
2 1 2 3
2 1 3 4
3 2 NULL NULL
從上面語句結果看出,也只影響了右表的數據(取出所有a表value對應為1的b表數據)
所以在左聯接查詢時ON后面的條件只會影響右表,相反右聯接查詢影響的就是左邊的表數據
如果用WHERE呢?我們看下下面的語句
語句5:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id where a.value = 1 語句6:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id where b.value = 1
結果5:
id value id value
-------------------------------
1 1 1 1
2 1 2 3
結果6:
id value id value
-------------------------------
1 1 1 1
可以從結果看出,這個影響的結果就是全部的表,就相當於通過ON條件聯接查詢查詢的結果,然后通過WHERE后面的條件取總體篩選
對於INNER JOIN 的ON條件會怎樣影響呢?先看下面語句執行結果
語句7: SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 語句8: SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND b.value = 1 語句9: SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id WHERE a.value = 1 語句10:SELECT * FROM dbo.TestJoinOnOrWhere_A AS a INNER JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id WHERE b.value = 1
結果7/9:
id value id value
-------------------------------
1 1 1 1
2 1 2 3
結果8/10:
id value id value
-------------------------------
1 1 1 1
上面通過WHERE和ON查詢出來的結果是一樣的,由此可看出,INNER JOIN 的ON條件和WHERE條件影響的都是一個效果,影響整體的查詢結果。
下面我們再來看下對於LEFT JOIN的三表查詢對於WHERE和ON影響的結果
語句11:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id
語句12:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND b.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id
語句13:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id AND b.value = 1
語句14:SELECT a.id AS a_id,a.value AS a_value,b.id AS b_id,b.value AS b_value,c.id AS c_id,c.value AS c_value FROM dbo.TestJoinOnOrWhere_A AS a LEFT JOIN dbo.TestJoinOnOrWhere_B AS b ON a.id = b.id AND a.value = 1 LEFT JOIN dbo.TestJoinOnOrWhere_C AS c ON b.id = c.id AND c.value = 2
結果11:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 1 1
2 1 2 3 2 2
3 2 NULL NULL NULL NULL
結果12:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 1 1
2 1 NULL NULL NULL NULL
3 2 NULL NULL NULL NULL
結果13:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 1 1
2 1 2 3 NULL NULL
3 2 NULL NULL NULL NULL
結果14:
a_id a_value b_id b_value c_id c_value
-----------------------------------------------------
1 1 1 1 NULL NULL
2 1 2 3 2 2
3 2 NULL NULL NULL NULL
通過以上三表數據查詢結果,可以看出,LEFT JOIN 查詢,對於ON的單獨表條件始終只會影響條件表的右表(如,a.value=1會影響b表關聯的a表value字段值為1的行,並不會限制a表的數據只顯示value=1的行),RIGHT JOIN 影響效果恰恰相反
在使用ON條件時LEFT JOIN影響的是右側的第二張第三張表,並不會對最左側的表影響,所以對於a,b,c,三張表,a表數據是不受ON條件影響的,只會影響聯接查詢后的b或c數據
而WHERE就相當於在WHERE條件之前查詢的數據當着一個表,然后通過WHERE條件進行篩選數據,所以影響的是整體。
創建於:2015-04-03
本文來自wl131710,轉載請注明出處:http://www.cnblogs.com/wanglu/p/4390612.html