SQLServer應用技巧:內(nèi)部連接和外部連接中NULLS的影響

字號:

SQL Server 開發(fā)人員必須了解兩件事情:首先,內(nèi)部連接和外部連接的差異;其次,NULLS對兩種連接操作的影響。這篇文章就涵蓋了這兩個方面。
    讓我們一步步來分析問題。首先,內(nèi)部連接和外部連接的差異,然后,查詢中NULLS的影響。為了研究內(nèi)部連接和外部連接的差異,我們需要一些樣例數(shù)據(jù)。
    假設(shè)我們有兩個數(shù)據(jù)表T1和T2,每個表中都含有數(shù)據(jù)列Testjoin。在數(shù)據(jù)表T1中,Testjoin列的數(shù)據(jù)值是1,2,3。在T2中,Testjoin列的數(shù)據(jù)值是NULL,2,3?;赥estjoin列的內(nèi)部查詢將只會返回兩行,其中數(shù)值1和NULL無法連接。然而當為外部連接時,數(shù)值1和NULL卻可以連接。例如,下面查詢語句的返回值就是那些下了訂單的客戶所在的行。
    SELECT CustomerID, OrderID FROM Customers Inner Join Orders
    On Customers.CustomerID = Orders.CustomerID
    (在許多商務交易中,這么做是有根據(jù)的,一些商務交易中,甚至規(guī)定了客戶必須至少下一個訂單。在我看來,數(shù)據(jù)庫的定義階段就應該反映這些商務交易規(guī)則,而不是在某些中間階段。當然,也存在著一些不同的情況。)
    下面是一個外部連接:
    SELECT CustomerID, OrderID FROM Customers LEFT OUTER JOIN Orders
    OnOrders.CustomerID = Customers.CustomerID
    它的返回值是所有的客戶列表,而不管客戶是否下了訂單。
    運行列表A中的腳本來創(chuàng)建一個測試表格.
    下面的SQL語句對外部連接和內(nèi)部連接進行了比較:
    SELECT InnerOuter.T1.T1ID, InnerOuter.T1.NameAS Name1,
        InnerOuter.T2.T2ID, InnerOuter.T2.NameAS Name2
    FROM InnerOuter.T1 LEFT OUTER JOIN
        InnerOuter.T2 ON InnerOuter.T1.T1ID = InnerOuter.T2.T1ID
    當運行了腳本中的兩個查詢之后,你會發(fā)現(xiàn)內(nèi)部連接返回兩行,而外部連接返回了三行。即使再添加第三個數(shù)據(jù)表,結(jié)果仍是遵循同樣的規(guī)則。如列表B示:
    如果你在select查詢語句中加了第三個表格,仍會得到同樣的結(jié)果:內(nèi)部連接返回兩行,外部連接返回三行。如列表C示:
    下面看看NULLS對不同的集合函數(shù)的影響。為了更好的理解,在表T2上增加一列空的money列,稱為Amount。在T2種增加一些行數(shù)據(jù),如下所示:
    T2ID T1ID Name Amount
    1 1 T2Text1 NULL
    2 NULL T2Text2 NULL
    3 3 T2Text3 120.0000
    4 1 T2Text4 123.0000
    5 1 T2Text5 234.0000
    6 3 T2Text6 345.0000
    NULL NULL NULL NULL
    有三行數(shù)據(jù)T1ID列的值是1,其中有一行的Amount值是NULL。有兩行數(shù)據(jù)的T1ID值是3,這兩行數(shù)據(jù)的Amount值都不為空(你還可以增加更多的行,但要確保行數(shù)目和Amount列為NULL的數(shù)目也不同)。