SQL Server學習筆記-連接
阿新 • • 發佈:2018-12-01
list offer 內連接 rst resource employ sco tab ssi
第四章-連接
內部連接
語法結構
SELECT <select list> FROM <first_table> <join_type> <second_table> [ON <join_condition>]
使用範例
SELECT Person.BusinessEntity.* FROM Person.BusinessEntity INNER JOIN HumanResources.Employee ON Person.BusinessEntity.BusinessEntityID = HumanResources.Employee.BusinessEntityID;
內連接具有排他特性.
INNER JOIN類似於WHERE
外連接
外連接的簡易語法
SELECT <SELECT list> FROM <the table you want to be the "LEFT" table> <LEFT|RIGHT> [OUTER] JOIN <table you want to be the "RIGHT" table> ON <join condition>
外連接本質上是包含的.
假設要知道具體折扣信息, 每一種折扣的數量和哪些商品打折.
SELECT sso.SpecialOfferID, Description, DiscountPct, ProductID FROM Sales.SpecialOffer sso LEFT JOIN Sales.SpecialOfferProduct ssop ON sso.SpecialOfferID = ssop.SpecialOfferID WHERE sso.SpecialOfferID != 1;
LEFT JOIN保留的是左側表的字段, 如果右側表中不存在與左側表匹配的字段, SQL Server會為其他任意值填充NULL.
RIGHT JOIN保留的是右側表的字段, 如果左側表中不存在與右側表匹配的字段, SQL Server會為其他任意值填充NULL.
SELECT sso.SpecialOfferID, Description, DiscountPct, ProductID FROM Sales.SpecialOffer sso LEFT JOIN Sales.SpecialOfferProduct ssop ON sso.SpecialOfferID = ssop.SpecialOfferID WHERE sso.SpecialOfferID != 1; SELECT sso.SpecialOfferID, Description, DiscountPct, ProductID FROM Sales.SpecialOfferProduct ssop RIGHT JOIN Sales.SpecialOffer sso ON ssop.SpecialOfferID = sso.SpecialOfferID WHERE sso.SpecialOfferID != 1;
返回與任何產品不關聯的折扣名稱
SELECT Description FROM Sales.SpecialOffer sso LEFT JOIN Sales.SpecialOfferProduct ssop ON sso.SpecialOfferID = ssop.SpecialOfferID WHERE sso.SpecialOfferID != 1 AND ssop.SpecialOfferID IS NULL; SELECT Description FROM Sales.SpecialOfferProduct ssop RIGHT JOIN Sales.SpecialOffer sso ON ssop.SpecialOfferID = sso.SpecialOfferID WHERE sso.SpecialOfferID != 1 AND ssop.SpecialOfferID IS NULL;
NULL值不等於NULL值.
IF (NULL = NULL) PRINT ‘It Does‘ ELSE PRINT ‘It Doesn‘‘t‘
處理更復雜的外部連接
-- 返回所有供應商的地址
SELECT v.VendorName, a.Address
FROM Vendors v
LEFT JOIN VendorAddress va
ON v.VendorID = va.VendorID
LEFT JOIN Address a
ON va.AddressID = a.AddressID;
SELECT v.VendorName, a.Address
FROM VendorAddress va
JOIN Address a
ON va.AddressID = a.AddressID
RIGHT JOIN Vendors v
ON v.VendorID = va.VendorID;
-- 使用分組連接
SELECT v.VendorName, a.Address
FROM Vendors v
LEFT JOIN (
VendorAddress va
JOIN Address a
ON va.AddressID = a.AddressID
)
ON v.VendorID = va.VendorID;
完全連接
FULL JOIN將左右兩側的數據全部匹配, 並返回所有的記錄. 無論記錄在JOIN的哪一側.
FULL JOIN查詢出來是兩個表的並集.
SELECT a.Address, va.AddressID, v.VendorID, v.VendorName FROM VendorAddress va FULL JOIN Address a ON va.AddressID = a.AddressID FULL JOIN Vendors v ON va.VendorID = v.VendorID;
交叉連接
交叉連接是將JOIN左側的所有記錄與另一側的所有記錄連接.
交叉連接返回的是JOIN兩側表的所有記錄的笛卡爾積.
交叉連接使用範例
SELECT v.VendorName, a.Address FROM Vendors v CROSS JOIN Address a;
聯合
JOIN 將信息水平連接(添加更多列)
UNION 將數據垂直連接(添加更多行)
UNOIN查詢的關鍵點
- 所有聯合的查詢必須在SELECT列表中有相同的列數.
- UNION返回的結果集的標題(列名)僅從第一個查詢獲得.
- 查詢中的對應列的數據類型必須隱式一致.
- UNION查詢的默認返回選項為DISTINCT, 而不是ALL.
UNION使用範例:
SELECT FirstName + ‘ ‘ + LastName AS Name FROM Person.Person pp JOIN Person.EmailAddress pe ON pp.BusinessEntityID = pe.BusinessEntityID JOIN Sales.Customer sc ON pp.BusinessEntityID = sc.CustomerID UNION SELECT FirstName + ‘ ‘ + LastName AS Name FROM Person.Person pp JOIN Person.EmailAddress pe ON pp.BusinessEntityID = pe.BusinessEntityID JOIN Purchasing.Vendor pv ON pp.BusinessEntityID = pv.BusinessEntityID
UNION去除重復行, SQL Server會將具有相等NULL列的行視為重復行.
-- 查詢添加特價供應產品的名稱 SELECT P.ProductNumber, ‘Less than 100 left‘ AS SpecialOffer FROM Production.Product P JOIN Production.ProductInventory I ON I.ProductID = P.ProductID WHERE I.Quantity < 100 UNION SELECT P.ProductNumber, SO.Description FROM Production.Product P JOIN Sales.SpecialOfferProduct O ON P.ProductID = O.ProductID JOIN Sales.SpecialOffer SO ON SO.SpecialOfferID = O.SpecialOfferID WHERE O.SpecialOfferID > 1
小結
- 要排除不匹配的字段的時候 使用內部鏈接(INNER JOIN | JOIN)
- 要檢索盡可能匹配的數據, 但又要包含JOIN一側的表的所有數據, 使用外部鏈接.(LEFT | RIGHT OUTER JOIN)
- 要檢索盡可能匹配的數據, 但又要包含JOIN兩側的表的所有數據, 使用完全外連接.(FULL OUTER JOIN)
- 要基於兩個表的記錄建立笛卡爾積時, 使用交叉連接.(CROSS JOIN)
- 要將第二個查詢結果附加到第一個查詢結果時, 使用聯合.(UNION | UNION ALL)
練習題
針對AdventureWorks數據庫編寫一條查詢語句, 要求返回Name列並包含NationalIDNumber為112457891的雇員的姓.
SELECT P.LastName AS Name FROM Person.Person P JOIN HumanResources.Employee E ON P.BusinessEntityID = E.BusinessEntityID WHERE E.NationalIDNumber = ‘112457891‘;
針對AdventureWorks數據庫編寫一條查詢語句, 要求返回所有產品的ID和Name列, 包括沒有特價供應的所有產品和有No Discount特價供應的所有產品.
SELECT P.ProductID, P.Name FROM Production.Product P LEFT JOIN Sales.SpecialOfferProduct SSP ON P.ProductID = SSP.ProductID WHERE SSP.SpecialOfferID IS NULL UNION SELECT P.ProductID, P.Name FROM Production.Product P JOIN Sales.SpecialOfferProduct SSP ON P.ProductID = SSP.ProductID JOIN Sales.SpecialOffer SSO ON SSO.SpecialOfferID = SSP.SpecialOfferID WHERE SSO.Description = ‘No Discount‘;
SQL Server學習筆記-連接