Reputation: 841
I have 3 tables and I have to inner join Table A with Table B but a left outer between Table A and Table C.
Can I combine outer and inner join in the same query? I can nest queries and attain the desired result but I am unable to do both the joins in the same query. It appears that in other SQL languages, the order of joining is important. Is this the case in SQL Server as well?
Ok, here's the scenario.
Consider 3 tables. Table A, Table F, Table D.
I will need the recordset to contain all rows in D irrespective of whether it exists in F (after it's inner joined with A). So, a outer join comes to mind. What I would need is:
Upvotes: 18
Views: 64247
Reputation: 45096
This comes up on 1 to zero or many where the many has a FK.
Two approaches
order of the on
put the outer
join last
Unfortunate you changed table names. I will use the later names.
declare @TableD TABLE (PeopleID int primary key, Name varchar(10));
INSERT INTO @TableD VALUES
(1, 'Chris')
, (2, 'Cliff')
, (3, 'Heather');
declare @TableA TABLE (ThingID int primary key, ThingName varchar(10))
INSERT INTO @TableA VALUES
(14, 'Bike')
, (17, 'Trailer')
, (18, 'Boat');
declare @TableF TABLE (PeopleID int, ThingID int, primary key (PeopleID, ThingID));
INSERT INTO @TableF VALUES
(1, 18)
, (1, 17)
, (2, 14);
SELECT D.Name, A.ThingName
FROM @TableD D
LEFT JOIN @TableF F
JOIN @TableA A
ON A.ThingID = F.ThingID
ON F.PeopleID = D.PeopleID
order by D.Name, A.ThingName;
SELECT D.Name, A.ThingName
FROM @TableF F
JOIN @TableA A
ON A.ThingID = F.ThingID
right join @TableD D
ON D.PeopleID = F.PeopleID
order by D.Name, A.ThingName;
Name ThingName
---------- ----------
Chris Boat
Chris Trailer
Cliff Bike
Heather NULL
Upvotes: 0
Reputation: 3859
For my case, I needed to put table aliases for my query to work properly:
SELECT * FROM ("purchased_items" p1
INNER JOIN "purchase_orders" po1 ON (po1."id" = p1."purchase_order_id")) AS p4
LEFT OUTER JOIN (purchased_items p2
INNER JOIN "purchase_orders" po2 ON (po2."id" = p2."purchase_order_id")) AS p5
ON (p4.item_variant_id = p5.item_variant_id AND p4.delivery_date < p5.delivery_date)
WHERE p5.delivery_date IS NULL AND p4.delivered <> 0
Upvotes: 11
Reputation: 96552
The problem may not specifically be the join (Anthony showed you how to do wht you described to us).Remember that people often have problems using left joins becasue they try to put something in the where clause referncing the table on the right side of the join thus converting it from an outer join to an inner join (unless you are looknig for those records where the second table field is null which gives you the records in the first table and not the secodn one).
We could help you better if we say the actual code you were using that wasn;t producting the desired results as well as some sample data and sample results.
Upvotes: 0
Reputation: 88796
The order shouldn't matter.
Here's a Venn Diagram from Wikimedia Commons. Regardless of the query order, you're going to get the overlap between circles A and B, with nulls for C's columns where C isn't overlapping the combination of A and B.
Upvotes: 2
Reputation: 7994
From your follow-up, it sounds like you want a 'conditional' inner join.
Essentially, an "If A and B have a record, INNER JOIN to C".
However, you are likely running into the problem where the INNER JOIN in your query is not showing records where A has no records associated to B or C. If they are at the same 'scope', the INNERS will always run, you can't conditionally have them run based on their order.
You either have to use two LEFT joins and filter out the records you don't want, or alternatively use a View to scope the INNER JOIN.
Ex. A LEFT JOIN vw_MyView ON A.ID=vw_MyView.A_ID
Where MyView has tables B and C with your INNER JOIN. This will allow the INNER JOIN to be run inside of the view, and then you can LEFT JOIN to the results.
Upvotes: 1
Reputation: 53824
If I understand correctly you want something like this:
select
*
from
a
left outer join c
inner join b on c.bID = b.ID
on a.cID = c.ID
Upvotes: 21
Reputation: 3206
Yes you can do both is the same query, and yes the order is important.
Upvotes: 0
Reputation: 189447
Sure you can do the join in the same query:-
FROM TableA a
INNER JOIN Table b ON a.TableA_ID = b.TableA_ID
LEFT OUTER JOIN Table c ON a.TableA_ID = c.TableA_ID
Upvotes: 4
Reputation: 8356
You can use both inner and outer joins in the same query, but their order is important. See this question:
Inner join & outer join; is the order of tables in from important?
Upvotes: 2