2016-11-30 2 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 JOIN возвращает результаты только с идентичными отметками времени). – Uueerdo

+2

^^ Да, пожалуйста, разместите структуры таблиц, чтобы мы могли дать точный ответ, не догадываясь. Но проблема заключается в использовании 'FROM OrderDetails, Customers', в котором вы создали декартово произведение с неявным внутренним соединением из-за синтаксиса запятой. –

+0

Ссылка, которую вы включили, фактически не показывает схему. Пожалуйста, отредактируйте вопрос, чтобы добавить инструкции 'CREATE TABLE' непосредственно здесь. –

ответ

0

Вы должны будете использовать Orders таблицу присоединиться к Customers из OrderDetails так OrderDetails не содержит customerid, которая необходима для вас, чтобы добраться до этого customers таблица.

Лучше запрос будет:

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

Замените запятую (которая является сокращением для CROSS JOIN) другим NATURAL 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

Смежные вопросы