2014-11-25 4 views
2

Я изучал базу данных Northwind. Существует один вид, называемый «Счет», довольно сложный.Заказ внутреннего соединения

Я попытался сменить исходный sql (вытащить последнее внутреннее соединение, слиться с другим внутренним заявлением объединения).

'Официальный' код, чтобы получить счет-фактуру: (правильный)

SELECT * 
FROM   dbo.Shippers  as shipper 
INNER JOIN  dbo.Products  as product 
INNER JOIN  dbo.Employees as employee 
INNER JOIN  dbo.Customers as customer 
INNER JOIN  orders   as orders 
ON customer.CustomerID = orders.CustomerID 
ON employee.EmployeeID = orders.EmployeeID 
INNER JOIN  dbo.[Order Details] 
ON orders.OrderID = dbo.[Order Details].OrderID 
ON product.ProductID = dbo.[Order Details].ProductID 
ON shipper.ShipperID = orders.ShipVia 

Моя первая попытка: (не работает)

SELECT * 
    FROM   dbo.Shippers  as shipper 
    INNER JOIN  dbo.Products  as product 
    INNER JOIN  dbo.Employees as employee 
    INNER JOIN  dbo.Customers as customer 
    INNER JOIN  orders   as orders 
    INNER JOIN  dbo.[Order Details] 
    ON orders.OrderID = dbo.[Order Details].OrderID 
    ON product.ProductID = dbo.[Order Details].ProductID 
    ON shipper.ShipperID = orders.ShipVia 
    ON customer.CustomerID = orders.CustomerID 
    ON employee.EmployeeID = orders.EmployeeID 

Моя вторая попытка (работы):

select  * 
from Orders as orders 
    inner join Shippers as ships 
     on ships.ShipperID = orders.ShipVia 
    inner join [Order Details] as ods 
     on ods.OrderID = orders.OrderID 
    inner join Products as products 
     on ods.ProductID = products.ProductID 
    inner join Customers as customers 
     on customers.CustomerID = orders.CustomerID 

Оба они возвращают 2155 строк записи.

Вот ссылка на таблицу структуры: enter image description here

Мой вопрос, почему «моя первая попытка» не так ли? Кроме того, как вы думаете, моя вторая попытка правильная?

Благодаря

+0

«Официальный» код работает. Все еще проверяйте синтаксис. @John Woo – CodeFarmer

+1

Неправильный синтаксис INNER JOIN приводит к ошибке. Проверьте этот синтаксис из MSDN: http://msdn.microsoft.com/en-us/library/bb208854(v=office.12).aspx –

+0

В чем проблема с первой попыткой? Вы получаете синтаксическую ошибку? Если да, можете ли вы поделиться им? – Mureinik

ответ

2

Каждые ON пункт используется для указания Соединить условия для наиболее немедленного п предшествующего JOIN что до сих пор не имело ON указано.

Итак, отступы, чтобы показать, как они совмещая:

SELECT * 
FROM   dbo.Shippers  as shipper 
INNER JOIN  dbo.Products  as product 
    INNER JOIN  dbo.Employees as employee 
     INNER JOIN  dbo.Customers as customer 
      INNER JOIN  orders   as orders 
       INNER JOIN  dbo.[Order Details] 
       ON orders.OrderID = dbo.[Order Details].OrderID 
      ON product.ProductID = dbo.[Order Details].ProductID 
     ON shipper.ShipperID = orders.ShipVia 
    ON customer.CustomerID = orders.CustomerID 
ON employee.EmployeeID = orders.EmployeeID 

И наиболее глубоко вложенным JOIN будет выполняться первым. Таким образом, в то время как внутренняя большинство присоединиться кажется правильным (присоединение orders к Order Details с ON пунктом orders.OrderID = dbo.[Order Details].OrderID), следующего из неверен - мы пытаемся присоединиться customer к результату предыдущего присоединиться (или orders и order details), но с предложением ONproduct.ProductID = dbo.[Order Details].ProductID - и это неправильно, потому что мы еще не присоединились к таблице product.

Вы можете попробовать перестановке их как:

SELECT * 
FROM   dbo.Shippers  as shipper 
INNER JOIN  dbo.Products  as product 
    INNER JOIN  dbo.Employees as employee 
     INNER JOIN  dbo.Customers as customer 
      INNER JOIN  orders   as orders 
       INNER JOIN  dbo.[Order Details] 
       ON orders.OrderID = dbo.[Order Details].OrderID 
      ON customer.CustomerID = orders.CustomerID 
     ON employee.EmployeeID = orders.EmployeeID 
    ON product.ProductID = dbo.[Order Details].ProductID 
ON shipper.ShipperID = orders.ShipVia 

Где сейчас по крайней мере, каждый ON пункт имеет дело с точки зрения таблицы псевдонимов, которые находятся в области видимости для каждого соединения.

Однако, я обычно рекомендую (кроме сложных соединений) следовать шаблону:

FROM a 
INNER JOIN b 
    ON a.column = b.column 
INNER JOIN c 
    ON a_or_b.column = c.column 
... 

Где каждый ON пункта хранится рядом с JOIN оговорки, что это на самом деле с указанием условий, значительно как ваша вторая попытка. Я не вижу причины пытаться получить все из JOIN s, чтобы они возникли в верхней части FROM.

+0

@Codefarmer: Damien абсолютно прав. Один за другим внутренним соединением ведет себя как вложенный подзапрос. Как показано в официальном коде, Inner most join orders объединяется с другими таблицами, чем приходит таблица заказов с таблицами с другими таблицами. И, следовательно, перестановка является одним из факторов INNER JOIN. –

0

в вашей 1-ой попытки, вы не связывал Грузовладелец заказать столик.

SELECT * 
    FROM   dbo.Shippers  as shipper 
    INNER JOIN  dbo.Products  as product 
    INNER JOIN  dbo.Employees as employee 
    INNER JOIN  dbo.Customers as customer 
    INNER JOIN  orders   as orders 
    INNER JOIN  dbo.[Order Details] 
    ON orders.OrderID = dbo.[Order Details].OrderID 
    ON product.ProductID = dbo.[Order Details].ProductID 
    ON shipper.ShipperID = orders.ShipVia 
    ON customer.CustomerID = orders.CustomerID 
    ON employee.EmployeeID = orders.EmployeeID 

2ndly при использовании соединения, вы должны упомянуть столбцы два стола, на котором объединение будет сделано.

поэтому, когда вы присоединяетесь к x и присоединяетесь к y, вы должны указать столбец x и столбец y. в противном случае это будет декартово произведение. когда вы присоединяетесь сразу, вы должны указать колонку.

во втором запросе идеальная практика связывает всю связанную таблицу 1-го. вы можете переписать это нравится:

select  * 
from Orders as orders 
    inner join Shippers as ships 
     on orders.ShipVia= ships.ShipperID 
    inner join Customers as customers 
     on orders.CustomerID = customers.CustomerID 
    inner join [Order Details] as ods 
     on orders.OrderID = ods.OrderID 

    inner join Products as products 
     on ods.ProductID = products.ProductID 
Смежные вопросы