Condition between two join in SQL - sql

I have 3 tables and i want to join two of them with a condition.
For exemple if i have table A, table B and Table C, i'd like to have JOIN AB or JOIN BC.
Does something like this exists ?
SELECT *
FROM B
(JOIN A
ON (B.b=A.id_a)
OR (B.b=A.id_b))
OR
(JOIN C
ON (B.b=C.id_a)
OR (B.b=C.id_b))
WHERE B.a=1001485422

You can do both joins at once
select *
from
b
left join
a on b.b in (a.id_a, a.id_b)
left join
c on b.b in (c.id_a, c.id_b)
where b.a = 1001485422

Related

SQL join on three tables, lines that exist in 2 tables but not the third

Please I need your help.
Suppose that we have 3 tables A, B and C as shown in the image below:
I want to get lines in the table A that exist or not exist in table B, and lines in table C that exist or not exist in table B, using one sql request.
I have tried this but doesn't work :
SELECT A.ATS0804, C.ATS0207, A.ATS0959, A.ATS0802, B.ATS0827
FROM
ISUT183.ENS0042 B
RIGHT JOIN ISUT183.ENS0038 A
ON B.ENS0038K = A.ATS0804
RIGHT JOIN ISUT183.EN00041 C
ON B.EN00041K = C.AT02812
WHERE ( C.ATS0207 = '0001757430'
AND B.ATS0823 = '9999-01-01'
AND A.ATS0803 = '9999-01-01'
AND A.ATS0959 = '61384352001'
AND A.ATS0802 ='01.01.2010'
) ;
you can do a cross join too:
with AB as (
select * from A left outer join B on A.ID1=B.ID1
),
AC as (
select * from C left outer join B on C.ID2=B.ID2
)
select * from AB CROSS JOIN AC
use where exists and where not exists clauses
If you test equality into table B in where clause, the left outer join or right outer join dont take null
You dont have join between A and C, then you can do a UNION ALL
but you must take columns of same type in selects clause (ID1 same type of ID2)
select * from (
select 'A-B' typejoin, A.ID1 as IDA_OR_C, B.ID1 as IDB from A left outer join B on A.ID1=B.ID1
union all
select 'A-C' typejoin, C.ID2 as IDA_OR_C, B.ID2 as IDB from C left outer join B on C.ID2=B.ID2
) tmp
where ....

Stuck on multiple table filtering query

Ok so I will try to simplify the problem that I have.
I have 4 tables:
TableA:
OneID
TableB:
OneID (FK to TableA)
TwoID (FK to TableC)
TableC:
TwoID
ThreeID (FK to TableD)
TableD:
ThreeID
I need a query to retrieve data from all 4 of these tables.
The query criteria is:
want to inner join tables A, B, C
want to join above result with table D with the following conditions:
if a record is in Table D but not in Table C, then it must always be present in the results
otherwise if a record is in Table D and Table C, then it should only be present if it is in the result of the A,B,C join
The scenario you have described is not really possible (or at least they are not really logical)
if a record is in Table D but not in Table C, then it must always be present in the results
The only way a record could be "in Table D and not in Table C" is if the foreign key is null in table D, with no link from table D to tables A or B there is no other way you could define a record as being present in D and not in C:
otherwise if a record is in Table D and Table C, then it should only be present if it is in the result of the A,B,C join
Again, the only way this could happen is with NULLABLE foreign keys. Regardless I think any of the below will get you the results you require:
SELECT A.OneID, B.TwoID, c.ThreeID, D.FourID
FROM D
LEFT JOIN (C
INNER JOIN B
ON B.TwoID = C.TwoID
INNER JOIN A
ON A.OneID = B.OneID)
ON C.ThreeID = D.ThreeID;
Or
SELECT A.OneID, B.TwoID, c.ThreeID, D.FourID
FROM A
INNER JOIN B
ON B.OneID = A.OneID
INNER JOIN C
ON C.TwoID = B.TwoID
RIGHT JOIN D
ON D.ThreeID = C.ThreeID
Or
SELECT A.OneID, B.TwoID, c.ThreeID, D.FourID
FROM A
INNER JOIN B
ON B.OneID = A.OneID
INNER JOIN C
ON C.TwoID = B.TwoID
INNER JOIN D
ON D.ThreeID = C.ThreeID
UNION ALL
SELECT NULL, NULL, NULL, FourID
FROM D
WHERE ThreeID IS NULL;
Examples on SQL Fiddle
The first two have the same execution plan, it is just a matter of preference, I personally dislike using RIGHT JOIN because it makes queries feel like they in the wrong order i.e bottom to top, but this is purely my preference. The last query may perform better depending on the cardinality of your data and any indexes you have
EDIT
With your revised criteria I think the easiest way to implement this is with a UNION ALL:
SELECT A.OneID, B.TwoID, c.ThreeID, d3 = D.ThreeID
FROM A
INNER JOIN B
ON B.OneID = A.OneID
INNER JOIN C
ON C.TwoID = B.TwoID
INNER JOIN D
ON D.ThreeID = C.ThreeID
UNION ALL
SELECT NULL, NULL, NULL, ThreeID
FROM D
WHERE NOT EXISTS (SELECT 1 FROM C WHERE C.ThreeID = D.ThreeID);
Example on SQL Fiddle
I am not 100% sure I understood you correctly but I will try to help anyway. It seems that you need to do FULL OUTER JOIN on table D:
SELECT
*
FROM
TableA AS A INNER JOIN
TableB AS B ON B.A_Id = A.Id INNER JOIN
TableC AS C ON C.B_Id = B.Id FULL OUTER JOIN
TableD AS D ON D.C_Id = C.Id
If I have misunderstood your requirements and you need more complicated criteria, you could just do FULL OUTER JOIN on all the tables and put extra conditions in WHERE part:
SELECT
*
FROM
TableA AS A FULL OUTER JOIN
TableB AS B ON B.A_Id = A.Id FULL OUTER JOIN
TableC AS C ON C.B_Id = B.Id FULL OUTER JOIN
TableD AS D ON D.C_Id = C.Id
WHERE
--if a record is in Table D but not in Table C, then it must always be present in the results
(D.Id IS NOT NULL AND C.Id IS NULL) OR
(
--otherwise if a record is in Table D and Table C, then it should only be present if it is in the result of the A,B,C join
(D.Id IS NOT NULL AND C.Id IS NOT NULL) AND
--want to inner join tables A, B, C
(A.Id IS NOT NULL AND B.Id IS NOT NULL AND B.Id IS NOT NULL)
)

Join two tables with one table

I need to do the following (I am not really sure if it is possible to do using SQL)
Table A
col_a_1, col_a_2, col_a_3
Table B
col_a_1, col_b_1, col_b_2....
Table C
col_a_1, col_c_1, col_c_2....
were col_a_1 is unique in table A. I need to join tables A, B, C such that every entry in table A will appear multiple times but every entry in table B and C appears only once and against the same col_a_1 of table A.
I know how to do it using the code. Is it also possible to do with SQL alone?
Thanks in advance.
You either want to use an outer join of some sort. either left or full outer.
SELECT A.*, B.*, C.*
FROM Table_A A
LEFT JOIN Table_B B on A.col_A_1 = B.Col_A_1
LEFT JOIN table_C C on A.Col_A_1 = C.Col_A_1
SELECT A.*, B.*, C.*
FROM Table_A A
FULL OUTER JOIN Table_B B on A.col_A_1 = B.Col_A_1
FULL OUTER JOIN table_C C on A.Col_A_1 = C.Col_A_1
or possibly a union result... just depends on what you're after.
SELECT A.*, B.*
FROM Table_A A
INNER JOIN Table_B B on A.col_A_1 = B.Col_A_1
UNION
SELECT A.*, C.*
FROM Table_A A
INNER JOIN Table_C C on A.col_A_1 = C.Col_A_1

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.