SQL Server: How to make a query with a left outer join + dependent inner join?
I'm facing with a join problem in sql server 2005 database. I've the following tables structure:
TableA --LEFT JOIN--> TableB --INNE开发者_StackOverflowR JOIN-->TableC
So if I write a query like this:
SELECT TableA.* FROM TableA
LEFT OUTER JOIN TableB ON TableA.keyOfB = TableB.key
INNER JOIN TableC ON TableB.keyOfC = TableC.key
where TableA.key = aValue
it read 0 record if there's not any TableB
record associated with TableA
record.
But TableB
is in outer join, so this is not what I expected. In other words, the INNER JOIN shouldn't have been considerer because there's not any TableB
record!
What I'm missing?
I think it has to do with the order of JOIN operations.
The result of (A LEFT OUTER JOIN B) INNER JOIN C, you want A LEFT OUTER (B INNER JOIN C).
Try dropping some () in there.
Or try reordering your JOINS to ... B INNER C RIGHT OUTER A to get (B INNER C) RIGHT OUTER A.
EDIT: Example of what I was thinking:
SELECT TableA.* FROM TableA
LEFT OUTER JOIN (TableB INNER JOIN TableC ON TableB.keyOfC = TableC.key)
ON TableA.keyOfB = TableB.key
WHERE TableA.key = aValue
Flipping to RIGHT OUTER:
SELECT TableA.* FROM TableB
INNER JOIN TableC ON TableB.keyOfC = TableC.key
RIGHT OUTER JOIN TableA ON TableA.keyOfB = TableB.key
WHERE TableA.key = aValue
NOTE: Forgive me if this is doesn't work, I haven't touched SqlServer since version 7.
This is behaving exactly as it should. Your link with TableC is through TableB so the link will not be connected if no TableB record.
Changing INNER JOIN
to LEFT OUTER
as well - although it is really an inner as far as the data concerned.
If you run query without INNER JOIN, there will be all records with TableB.key null, right? So next INNER JOIN can't find any matching record, that's why there is no result.
Use a virtual table for (B+C) join.
EDIT: Something like:
SELECT TableA.* FROM TableA
LEFT OUTER JOIN
(select key from TableB INNER JOIN TableC ON TableB.keyOfC = TableC.key) as TableBC
ON TableA.keyOfB = TableBC.key
where TableA.key = aValue
Here is the code as an example of using left out join for both table b and c.
declare @TableA table (Adata1 char(2), Adata2 char(2))
declare @TableB table (Bdata1 char(2), Bdata2 char(2))
declare @TableC table (Cdata1 char(2), Cdata2 char(2))
;Insert @TableA
Select 'A', 'A' union all
Select 'B', 'B' union all
Select 'C', 'C'
;Insert @TableB
Select 'Ab', 'Ab' union all
Select 'B', 'B' union all
Select 'C', 'C'
;Insert @TableC
Select 'A', 'A' union all
Select 'B', 'B' union all
Select 'Cb', 'Cb'
--Select * From @TableA
--Select * From @TableB
--Select * From @TableC
Select * from @TableA
LEFT OUTER JOIN @TableB on Adata1 = Bdata1
LEFT OUTER JOIN @TableC on Bdata1 = Cdata1
Results are:
Adata1 Adata2 Bdata1 Bdata2 Cdata1 Cdata2
A A NULL NULL NULL NULL
B B B B B B
C C C Cb NULL NULL
精彩评论