У меня есть три таблицы:Проблемы с INNER JOIN и LEFT/RIGHT OUTER JOIN
- Заказы
- OrderId, внутр PK
- CustomerId, внутр FK Клиенту, NULL разрешено
- Клиенты
- CUSTOMERID, внутр PK
- CompanyID, Int FK в компании, NULL не допускается
- Companie s
- CompanyID, Int PK
- Имя, NVARCHAR (50)
Я хочу, чтобы выбрать все заказы, независимо от того, если у них есть клиент или нет, и если у них есть клиент, а также название компании клиента.
Если я использую этот запрос ...
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Orders
LEFT OUTER JOIN Customers
ON Orders.CustomerId = Customers.CustomerId
INNER JOIN Companies
OM Customers.CompanyId = Companies.CompanyId
... он возвращает только те заказы, которые имеют клиента. Если я заменяю INNER JOIN
по LEFT OUTER JOIN
...
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Orders
LEFT OUTER JOIN Customers
ON Orders.CustomerId = Customers.CustomerId
LEFT OUTER JOIN Companies
OM Customers.CompanyId = Companies.CompanyId
... это работает, но я не понимаю, почему это необходимо, потому что отношения между Customers
и Companies
требуется: Клиент обязательно иметь компанию.
Альтернативный подход, который работает хорошо, кажется:
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Companies
INNER JOIN Customers
ON Companies.CompanyId = Customers.CompanyId
RIGHT OUTER JOIN Orders
OM Customers.CustomerId Orders.CustomerId
Этот запрос имеет ряд внутренних и внешних соединений, что я ожидал, но проблема в том, что трудно читать для меня, потому что у меня есть мой запрос в качестве запроса заказов в виду, где заказ является «корнем» выбора, а не компанией. Кроме того, использование RIGHT OUTER JOIN
для меня довольно незнакомо.
Последний запрос представляет собой небольшую часть запроса, созданного конструктором для отчетов отчетов служб SQL Server. Я пытаюсь написать запрос вручную без поверхности конструктора, потому что он очень переполнен, и у меня возникают проблемы с сохранением запроса после многих изменений, и в будущем ожидается больше изменений. Итак, я хочу как-то дать запрос понятной структуре.
Вопросы:
- Почему не запрашивает 1 работу, как я ожидал?
- Является ли запрос 2 правильным решением, хотя (или потому что?) Он использует два LEFT OTHER JOINS?
- Является ли запрос 3 правильным решением?
- Есть ли лучший способ написать запрос?
- Есть ли общие правила и практики, как написать запрос с большим количеством внешних и внутренних соединений в удобной для чтения форме?
Я не говорю, что вы не правы, но как может заказ не иметь клиента. Заказ - это комбинация продукта и клиента, безусловно, – DavidB
@DavidB: Не настоящая модель. Просто подумайте о «анонимных» заказах, где производственная компания имеет внутренние заказы на производство на складе без ссылки на клиентов ... или что-то в этом роде. – Slauma
Одним из решений здесь является наличие «анонимной» записи клиента, которую вы можете сопоставить для них, а не без клиента. Скорее всего, этот подход поможет и многим другим отчетам. –