Left outer join involving 3 tables - sql

I have 3 DB2 tables all having same key value columns. Now I want the data from table A with a condition along with the matching records from tables B and C. Suppose table A has 100 records for the condition (say, COLX = 'Y') then all the 100 records from table A along with the matching key records from B & C should be extracted (A.COL1, B.COL1 & C.COL1 are the key columns) Can someone please tell me how this can be done using left outer join ?

Something like this?
select *
from A
left outer join B on A.COL1=B.COL1
left outer join C on A.COL1=C.COL1
where A.COLX='Y'

Related

How to write an optimized SQL query?

How to write an optimized SQL query to get results in table 1 which are not in table 2 and table 3, similarly in table 2 which are not in table 1 and table 3 and for in table 3 which are not in table 1 and table 2
I'm trying to improve performance of my query that I'm Currently working on
TABLE A
LEFT JOIN B
LEFT JOIN C
WHERE B is NULL and C is NULL
UNION
TABLE B
LEFT JOIN A
LEFT JOIN C
WHERE A is NULL and C is NULL
UNION
TABLE C
LEFT JOIN A
LEFT JOIN B
WHERE A is NULL and B is NULL
Is there any way where we can avoid reading the table 3 times?
Try using a full outer join.
select a.*, b.*, c.*
from a full outer join b on
a.A_keys = b.B_keys
full outer join c on
a.A_keys = c.C_keys AND
b.B_keys = c.C_keys
As others have indicated because you did not supply sample data or join condition it is impossible to guess whether the second join (to c) requires conditions to both A and B or just A or just B. So you will need to work that bit out for your self.
For reference, a FULL OUTER JOIN is like doing a LEFT and RIGHT OUTER JOIN in one go. That is, it will return:
all records that match on both sides of the join (the INNER join), plus
all records that are in the LEFT table but not in the right (the LEFT outer join). Right table records will be NULL
all records that are in the RIGHT table but not in the left (the RIGHT outer join). Left table records will be NULL
I will leave it to you to add the "NULL filters" to get the records you are interested in.
So, unique from A, unique from B, unique from C ? As there are no other rows from other tables, I think you just want
SELECT * FROM A
UNION
SELECT * FROM B
UNION
SELECT * FROM C

SQL - Need to conditionally join based on value in TableB column

I need to know the rows in TABLE A that have join records in TABLE B based a column value in TABLE B, but I also need to return rows in which a row in TABLE A has no match in TABLE B.
It seems like I need a LEFT JOIN and a LEFT OUTER JOIN, so I'm not sure what to do there. I understand how to do each, but don't understand how to do them together.
The schema looks like:
TABLE_A
pk
TABLE_B
pk
a_fk
some_value
I need the joined rows where Table_A has no join record in Table_B OR Table_A has a join record row in Table_B (it can have many) in which some_value does not equal "thisValue"
Thanks.
A Left join is a left outer join. Outer joins preserve one of the tables which is what you are after so good guess.
SELECT *
FROM Table A
LEFT JOIN Table B
ON TableA.Column = TableB.Column
AND B.SomeValue <> 'ThisValue'
All of the rows with a match will have the B information populated all of those without will have nulls in the B data

Update records only once with LEFT OUTER JOIN

I am trying to UPDATE Table A with records in Table B based on a LEFT OUTER JOIN based on two columns of data. So, for example, the JOIN from Table A might be USA-4 to match Table B's USA-4. Returning a result of XYZ to a different column. The problem I am having is the Table B contains multiple USA-4's and as a result Table A appears to be updating more than once. Is there a way to fix this? A different JOIN type?
UPDATE tablea a
SET USA-4 = (SELECT distinct USA-4 FROM tableb b WHERE a.id=b.id)

Separated JOIN form main INNER JOINS's

I want to INNER JOIN some tables and then insert a condition where the entries of a table are dependant on another table (that was not joined with the others)
Something like this:
SELECT * FROM TABLE_A AS a
INNER JOIN TABLE_B AS b ON b.id_b=a.id_a
INNER JOIN TABLE_C AS c ON c.id_c=b.id_b
Now I want to add a condition (possibly a "WHERE" clause) that only selects the values in a field in TABLE_C that match another condition, the existence of a value in a field in TABLE_D
Possible statement:
WHERE c.code=d.another_code AND d.reg_number LIKE 999%
How do i declare in the query the TABLE_D, since I do not want to Join it with the others?
In other words, I want to intersect 3 sets (A,B,C) and the other one (set D) is intersected only with set C
The title of the question Run-time error '13': ... doesn't seem to match the content so I'll just answer the SQL part.
Maybe this is what you want?
SELECT * FROM TABLE_A AS a
INNER JOIN TABLE_B AS b ON b.id_b=a.id_a
INNER JOIN TABLE_C AS c ON c.id_c=b.id_b
WHERE c.code = -- or possiby IN instead of =
(SELECT another_code FROM TABLE_D WHERE another_code LIKE '999%')
If the subquery can return multiple rows you need to use WHERE c.code IN instead of WHERE c.code =

PL/SQL Using multiple left join

SELECT * FROM Table A LEFT JOIN TABLE B LEFT JOIN TABLE C
From the snippet above, TABLE C will left join into (TABLE B) or (data from TABLE A LEFT JOIN TABLE B) or (TABLE A)?
TABLE C will left join into 1. (TABLE B) or 2. (data from TABLE A LEFT JOIN
TABLE B) or 3. (TABLE A)?
The second. But The join condition will help you to understand more.
You can write:
SELECT *
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.ID = C.ID)
But you are able to:
SELECT *
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.id = C.id and B.code = C.code)
So, you can join on every field from previous tables and you join on "the result" (though the engine may choose its way to get the result) of the previous joins.
Think at left join as non-commutative operation (A left join B is not the same as B left join A) So, the order is important and C will be left joined at the previous joined tables.
The Oracle documentation is quite specific about how the joins are processed:
To execute a join of three or more tables, Oracle first joins two of
the tables based on the join conditions comparing their columns and
then joins the result to another table based on join conditions
containing columns of the joined tables and the new table. Oracle
continues this process until all tables are joined into the result.
This is the logic approach to handling the joins and is consistent with the ANSI standard (in other words, all database engines process the joins in order).
However, when the query is actually executed, the optimizer may choose to run the joins in a different order. The result needs to be logically the same as processing the joins in the order given in the query.
Also, the join conditions may cause some unexpected conditions to arise. So if you have:
from A left outer join
B
on A.id = B.id left outer join
C
on B.id = C.id
Then, you might have the condition where A and C each have a row with a particular id, but B does not. With this formulation, you will not see the row in C because it is joining to NULL. So, be careful with join conditions on left outer join, particularly when joining to a table other than the first table in the chain.
You need to mentioned the column name properly in order to run the query. Let´s say if you are using:
SELECT *
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.id = C.id and B.code = C.code)
Then you may get the following error:
ORA-00933:SQL command not properly ended.
So to avoid it you can try:
SELECT A.id as "Id_from_A", B.code as "Code_from_B"
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.id = C.id and B.code = C.code)
Thanks