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.
Related
Suppose I have a table t1 with:
ID CODE
1 A
1 B
1 C
2 C
2 D
And another table t2 that provides me the hierarchies. (so what inferior really means is that if code A, B and C all exist for a specific ID, we should really only use code A. and if code C and D both exist, we should really only use code C)
CODE INFERIOR
A B
A C
C D
How do I write the query in plsql that give me the following results?
ID CODE
1 A
2 C
Current query is for SQL-Server 2008, if there's any issue just tell me where your problem is and what your DBMS is and I'll try to adapt the code.
SELECT a.id, a.code
FROM t1 a
LEFT OUTER JOIN t2 b ON b.inferior = a.code
LEFT OUTER JOIN t1 c ON c.code = b.code and c.id=a.id
where c.code is null;
The idea is basically to try and match each entry of t1 with another entry that has the same id and shares a child-parent relationship. Once that's done, you simply need to find those who don't have a parent.
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
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)
)
I have three tables A, B, and C:
A
---------
a_pk | id
B
----------------------
b_pk | id | link | foo
C
----------------------
c_pk | id | link | bar
All records in B have a matching record in A; all records in C have a matching record in A, but records in B and C do not necessarily have to match each other. I want to get the set of results where A has a match in either B or C. Individually, the queries would be:
SELECT A.id, B.foo FROM A INNER JOIN B ON A.id = B.id
SELECT A.id, C.bar FROM A INNER JOIN C ON A.id = C.id
SELECT B.foo, C.bar FROM B FULL JOIN C ON B.id = C.id AND B.link = C.link
What would I need to fill in to make this work?
SELECT A.id, B.foo, C.bar FROM <join A, B, C>
I'm using Oracle if it makes a difference, and I would prefer to avoid using a subquery if possible.
[edit - for clarification]
I want only the records from A that have a match in either B or C.
Sounds like you need a left join. (I'm not very familiar with Oracle but I assume this should work.)
SELECT A.id, B.foo, C.bar
FROM A
LEFT OUTER JOIN B on A.id = B.id
LEFT OUTER JOIN C on A.id = C.id
WHERE B.id IS NOT NULL OR C.id IS NOT NULL
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