2016-11-30 135 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