I have three tables:
- Orders
- OrderId, int PK
- CustomerId, int FK for the client, NULL allowed
- Customers
- CustomerId, int PK
- CompanyId, int FK for company, NULL not allowed
- Companies
- CompanyId, int PK
- Name, nvarchar (50)
I want to select all orders, regardless of whether they have a client or not, and if they have a client, then also the name of the client's company.
If I use this query ...
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
... he only returns orders with the customer. If I replaced INNER JOIN with 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
... it works, but I don’t understand why it is necessary, because the connection between Customers and Companies is required: the client must have a company.
An alternative approach that works also looks like this:
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
This request has the number of internal and external associations that I expect, but the problem is that it is difficult to read for me, because I have my request as a request for orders in mind where the order is the "root" and not the company. Also, using RIGHT OUTER JOIN is pretty unfamiliar to me.
The final query is a small part of the query created by the designer for SQL Server Services reporting reports. I am trying to write a query manually without a constructor surface because it is very crowded and I am having problems saving the query after many changes, and more changes are expected in the future. So, I want to somehow provide a request for a readable structure.
Questions:
- Why not request 1 job, as I expected?
- Is query 2 the right solution, though (or because?) Does it use two LEFT OTHER JOINS?
- Is query 3 the right solution?
- Is there a better way to write a query?
- Are there any general rules and practices on how to write a query with a large number of external and internal connections in good readability?
Slauma
source share