Is it possible to do a 3 table join in MS-Access? - sql

I try to do a 3-table join in Access and it will not work. Is it possible?

I once had a problem when I tried
select
x,
y
from
A inner join
B on k=l inner join
C on f=g
This didn't work. But it works with parantheses:
select
x,
y
from (
A inner join
B on k=l ) inner join
C on f=g

All the various types of multi-table joins that are available in other flavour of SQL are permitted in MS-Access/Jet. For example, here's a straight three-table hierarchical example (a bit more real-world than the other answers here):
SELECT
x.FirstName,
x.Surname,
r.RegionName,
c.CountryName
FROM
(Customer x LEFT JOIN Region r
ON r.ID=x.RegionID)
LEFT JOIN Country c
ON c.ID=r.CountryID
Or did you want to know how to do it using the Visual Designer in MS-Access?

Yes, it's possible:
Select *
From A, B, C
Where A.a = B.b
And A.c = C.c
or
Select *
From A, B, C
Where A.a = B.b
And B.c = C.c

Access can do most types of joins (apart from a full outer) I wonder with your 3 table join if you are doing an ambiguous outer join? Have a look at this KB article for an explanation
support.microsoft.com/kb/124937

Related

Oracle SQL: How to convert multiple (+) WHERE clauses to LEFT JOINS? [duplicate]

This question already has answers here:
Oracle "(+)" Operator
(4 answers)
Closed last month.
I'm trying to convert some Oracle SQL code to regular SQL and am having trouble with the numerous variables in the SELECT statement, tables in the FROM statement, and (+) WHERE statements.
I have looked through similar posts but all provide simple examples with just 2 variables, 2 tables, and 1 (+) WHERE statement. I'm not sure how to apply what I'm seeing from the other forum posts to multiple variables, tables, and (+) WHERE statements.
SELECT
a.ID,
c.var1,
d.var2
FROM a, b, c, d, x, y
WHERE a.ID(+) = b.ID
AND c.var1(+) = b.var1
AND x.id(+) = y.id;
I tried to convert all the (+) WHERE statements to LEFT JOINs as shown below. I did 3 LEFT JOINS, one for each (+) WHERE statement:
SELECT
a.ID,
c.var1,
d.var2
FROM a, b, c, d, x, y
WHERE b.ID in
(SELECT b.ID
FROM b
LEFT JOIN a
ON a.ID = b.ID)
The query:
SELECT a.ID,
c.var1,
d.var2
FROM a, b, c, d, x, y
can be rewritten using ANSI-join syntax as:
SELECT a.ID,
c.var1,
d.var2
FROM a
CROSS JOIN b
CROSS JOIN c
CROSS JOIN d
CROSS JOIN x
CROSS JOIN y
If you add in the WHERE clause then WHERE c.var1(+) = b.var1 converts the CROSS JOIN to a LEFT OUTER JOIN from b to c. Similarly for the other join conditions.
Which gives you:
SELECT a.ID,
c.var1,
d.var2
FROM b
LEFT OUTER JOIN a ON a.ID = b.ID
LEFT OUTER JOIN c ON c.var1 = b.var1
CROSS JOIN d
CROSS JOIN y
LEFT OUTER JOIN x ON x.id = y.id;
fiddle

FROM Statement Giving an Error (3 Sources)

I am trying to SELECT a few things from tables A,B, and C, but when I try to LEFT JOIN, I keep getting an error. My code currently looks like this:
FROM (A LEFT JOIN B ON A.id = B.id), C
Am I not allowed to left join two tables and include the entirety of a third?
Thanks for your help.
EDIT
Here is a sample code:
SELECT A.ID, A.place, A.receipt, D.State, A.service, B.Description, C.ID, C.receipt, C.Source
FROM B, (A LEFT JOIN C ON A.receipt = C.receipt), D;
Access doesn't support combining cross-joins with other joins, so you will have to do the left join in a subquery, and then the cross-join:
FROM (SELECT * FROM A LEFT JOIN B ON A.id = B.id) As D, C

T-SQL: Wild Card as table name alias in select statement possible?

This is more of a curiosity than an actual applied question. Say you have a statement with multiple joins such as:
SELECT
a.name,
b.salary,
c.x
FROM
[table1] a
INNER JOIN [table2] b
ON a.key = b.key
INNER JOIN [table3] c
ON b.key = c.key
Now, say you were to make several more joins to other tables whose schema was unfamiliar, however you know:
the keys on which to make the join
that several of those tables has a column with the the name 'x'.
Is it possible to select 'x' from all tables that contain it, without explicitly referring to the table alias. So it would ave a similar results as this (if it were possible)
SELECT
a.name,
b.salary,
*.x
...
No this isn't possible.
You can use a.* to get all columns from a but it is not valid to use a wildcard as the table name.
#Martin Smith is correct that you can't use *.x and refer to columns from multiple tables. There is however a way to write a query that shows all columns x from tables where they exist without breaking if one or more of the tables do not have such column. It's a rather complicated way that (mis)uses scope resolution.
Lets say that some of the tables (b and d in the example) have a column named x, while some others (c here) do not have such column. Then you can replace INNER joins with CROSS APPLY and LEFT joins with OUTER APPLY and a query with:
SELECT
a.name,
a.salary,
b.x AS bx,
'WITHOUT column x' AS cx,
d.x AS dx
FROM
a
INNER JOIN b
ON a.aid = b.aid
LEFT JOIN c
ON a.aid = c.aid
LEFT JOIN d
ON a.aid = d.aid ;
would be written as:
SELECT
a.name,
a.salary,
bx,
cx,
dx
FROM
( SELECT a.*,
'WITHOUT column x' AS x
FROM a
) a
CROSS APPLY
( SELECT x AS bx
FROM b
WHERE a.aid = b.aid
) b
OUTER APPLY
( SELECT x AS cx
FROM c
WHERE a.aid = c.aid
) c
OUTER APPLY
( SELECT x AS dx
FROM d
WHERE a.aid = d.aid
) d ;
Tested at SQL-Server 2008: SQL-Fiddle

Selecting from three tables, distinct selections from one

I have three tables, I'll call them table A, B and C here. Table A has a one to many relation to B and B has a one to many relation with C. For this query, I only want disctinct values from C, but the query below will give me multpile C records that match B.
Right now my query is as such:
Select * from A Left Outer Join B on A.key = B.key Left Outer Join C on B.AltKey = C.AltKey
Any ideas?
Many thanks in advance.
Why are you using LEFT OUTER JOIN? Try switching that with plain old JOIN and see if you get what you're looking for.
Select distinct C.* from C
Left Outer Join B on C.a = B.a
Left Outer Join A on B.a = A.a

Inner joining one table against many others

I have a table A with columns (Id,Value)
and a table B with Columns (BId,Id,..)
and a table C with columns (CId,Id,...)
I need to perform an inner join on these tables as follows
select a.Id,a.Value from A a
inner join B b on b.Id=a.Id
inner join C c on c.Id=a.Id
where <many conditions on table B and C>
How can i achieve the same. Now when i just run the query
select a.Id,a.Value from A a
inner join B b on b.Id=a.Id
inner join C c on c.Id=a.Id
it doesnt return anything.. please help.
FYI when i run the joins separately it gives me the rows. I just want a union of them...
Sample data:
A
1
2
3
B
2
C
3
then i want to select
A
2
3
Thanks in advance.
So, following your comments, it appears that you want something like this:
select a.Id,a.Value from A a
inner join B b on b.Id=a.Id
where <many conditions on table B>
UNION ALL
SELECT a.Id, a.Value from A
inner join C c on c.Id=a.Id
where <many conditions on table C>
As long as the fields match on ID from A -> B and A -> C and you dont have any other join condition, you should be able to see the matching rows.
I could not understand your point about how the B and C Id do not match. if a.id=b.id and a.id=c.id, Doesn't it automatically imply b.id = c.id?
Anyways, in situations like these, I try to do outer join of A on B and C and see if the rows that I think are matching in fact do exist.
select a.Id,a.Value from A a
left outer join B b on b.Id=a.Id
left outer join C c on c.Id=a.Id
where (b.id is not null or c.id is not null)
/* Matching record found in b or c */
EDIT: Based on your requirement, you can use the approach that Lamak suggested above (Using UNION Alls) or if you are certain that for each record in A, you will only have one record in B and one in C at most and only one column, you can use the scalar sub query approach.