简体   繁体   中英

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 --INNER 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?

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

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM