2016-11-30 132 views
0

當我進入這個查詢,SQL爲什麼返回太多結果?

SELECT OrderDetails.OrderDetailID, Customers.CustomerName 
    FROM OrderDetails, Customers 
     NATURAL JOIN Products 
     NATURAL JOIN Customers 
WHERE SupplierID = 5; 

1001返回的記錄。

當我進入這個查詢,

SELECT OrderDetailID 
    FROM OrderDetails 
     NATURAL JOIN Products 
WHERE SupplierID = 5; 

共有11條記錄返回

正如你所期望的有91條記錄Customer表和11所導致第二個查詢返回和91 * 11 = 1001。然而,我不知道如何擺脫這一點,並防止在第一個查詢中返回重複的結果。

Duplicate Returns

架構的連接:http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all

+2

,我會在遠離自然連接,他們爲您節省打字沒有真正的利益和用少量從長遠來看,很多不可預測性(例如,稍後,在項目發展之後,「標準化」時間戳會被添加到表格中;現在您以前的工作NATURAL NATURAL只會返回具有相同時間戳的結果)。 – Uueerdo

+2

^^是的,請張貼表結構,以便我們可以提供準確的答案,而不用猜測。但問題是由於使用了'FROM OrderDetails,Customers',其中您使用逗號語法創建了帶有隱式內部聯接的笛卡爾產品。 –

+0

您包含的鏈接實際上並未顯示架構。請編輯問題直接在這裏添加「CREATE TABLE」語句。 –

回答

0

你需要使用Orders表從Customers加入OrderDetails因爲OrderDetails不包含需要你去了customeridcustomers表。

一個更好的查詢是:

SELECT orderDetails.OrderDetailID, customers.CustomerName 
    FROM OrderDetails orderDetails 
     INNER JOIN Orders orders on orderDetails.OrderID = orders.OrderID 
     INNER JOIN Customers customers on orders.customerID = customers.customerID 
     INNER JOIN Products products on prderDetails.ProductID = products.ProductID 
    WHERE products.SupplierID = 5; 

在這裏,我們避免Natural Joins因爲這些是不可預知的,寫SQL時,它總是一個好主意,儘可能明確。此外,我們使用Orders表獲得鏈接到customers

+0

「自然聯接...可能無法預測」 - 如果您擔心某種情況可能會「不可預測」,那麼您可以進行防守編碼(無論如何,這是一個好習慣) ?)例如使用具有特權的視圖。 – onedaywhen

0

用另一個NATURAL JOIN替換逗號(這是對CROSS JOIN的簡寫)。此外,使用NATURAL JOIN當你不需要使用範圍變量,即改變OrderDetails.OrderDetailID簡單OrderDetailID

SELECT OrderDetailID, CustomerName 
    FROM OrderDetails 
     NATURAL JOIN Orders 
     NATURAL JOIN Customers 
     NATURAL JOIN Products 
WHERE SupplierID = 5; 
+0

您可能不需要加入產品。 – onedaywhen