oracle sql full join with table a not in - sql

I have to tables (tbla and tblb) with each one col (id):
select * from tbla;
ID
---
1
3
5#A
select * from tblb;
ID
---
2
3
Now I need a full join:
select a.id, b.id
from tbla a
full outer join tblb b on b.id = a.id;
ID ID1
--------
1
3 3
5#A
2
... but without entries containing a #-sign in tbla.id
select a.id, b.id
from tbla a
full outer join tblb b on b.id = a.id
where a.id not like '%#%';
ID ID1
--------
1
3 3
why is the entry with id 2 from tblb missing?

Because when you do a full outer join, columns on either side can end up with a NULL value.
Explicitly check for NULL:
select a.id, b.id
from tbla a
full outer join tblb b on b.id = a.id
where a.id not like '%#%' or a.id is null;
(Originally, I had suggested moving the logic to the on clause. Alas, the full outer join keeps records in both tables, even when no records match the condition. So, moving the condition to the on clause doesn't fix anything.)

When you do outer joins, you have to do your filtering in the from clause. If you do it in the where clause your join effectively becomes an inner join.
So change this:
full outer join tblb b on b.id = a.id
where a.id not like '%#%'
to this
full outer join tblb b on b.id = a.id
and a.id not like '%#%'

You are doing a full join, but by specifying a.id in the where clause, you filter your result set afterwards.
To achieve what you want, you can either move the clause into the join condition:
select a.id, b.id
from tbla a
full outer join tblb b
on b.id = a.id
and a.id not like '%#%';
Or you can use nvl:
select a.id, b.id
from tbla a
full outer join tblb b on b.id = a.id
where nvl(a.id, 'n/a') not like '%#%';
Or explicitly allow NULL values for a.id:
select a.id, b.id
from tbla a
full outer join tblb b on b.id = a.id
where (a.id is null or a.id not like '%#%');

Related

Conditional join in SQL Server dependent on other table values

I need make a decision which table should be use in join statement depend on values in another table
I tried using CASE and COALESCE but can't achieve any success.
TableA has A and B and C and many other columns
TableB has ID and NAME columns
TableC has ID and NAME columns
My select statement is;
Select A.D, A.E, A.F From TableA A
If A.E = 1 then the following join should be used
left outer join TableB B ON A.B = B.ID
and B.NAME should be returned in the select statement
If A.E = 2 then the following join should be used
left outer join TableC C ON A.B = C.ID
and C.NAME should be returned in the select statement
Just add your conditions to the joins, and then use a case statement to pull the correct field to your result set e.g.
select A.D, A.E, A.F
, case when B.[Name] is not null then B.[Name] else C.[Name] end [Name]
from TableA A
left outer join TableB B ON A.B = B.ID and A.E = 1
left outer join TableC C ON A.B = C.ID and A.E = 2
Join tablea with the union of tableb with an extra column with value 1 and tablec with an extra column with value 2 and apply the conditions in the ON clause:
select
a.D, a.E, a.F, u.NAME
from tablea a
left join (
select *, 1 col from tableb
union all
select *, 2 col from tablec
) u on a.B = u.id and a.E = u.col

Is subtraction of inner join from full outer join some type of "join"?

Given two tables, is there a name for the result of subtracting inner join from full outer join, both on the same condition? Is it a type of "join"? Thanks.
It is not a type of join in SQL. You can write it as:
select . . .
from a full join
b
on a.id = b.id
where a.id is null or b.id is null;
If you are looking for ids that are in only one table, it can be more efficient to do:
select a.id
from a
where not exists (select 1 from b where b.id = a.id)
union all
select b.id
from b
where not exists (select 1 from a where a.id = b.id);

issue in sql join query formation

I have two tables Say A and B. A is master table and B is child table, from which I need values as below.
select A.Id, A.Name, B.Path from A,B where A.Id=B.Id
Now, I want to add column of 3rd table which is child of table 'B', say C i.e. C.File.
The value of C.File will be null if C.SubId=B.SubId is false else will return value when condition becomes true.
This is the exact definition of a left join:
SELECT a.id, b.name, b.path, c.file
FROM a
JOIN b ON a.id = b.id
LEFT JOIN c ON b.subid = c.subid
You need to LEFT JOIN your third table from what I can gather.
SELECT A.Id, A.Name, B.Path, C.file
FROM tableA a
INNER JOIN tableB b ON a.id = b.id
LEFT JOIN tableC c ON b.subid = c.subid
Simply Join all the three tables using INNER JOIN
select A.Id, A.Name, B.Path ,C.File
FROM A
INNER JOIN B
ON A.Id=B.Id
INNER JOIN C
ON C.SubId=B.SubId

How do you display dynamic data using full outer join?

I have a table A and B with a common ID field. I would like to do a full outer join on these tables, selecting the ID and either 'table A' or 'table B', depending on which table the ID came from.
SELECT ID, ['tableA'|'tableB']
FROM A FULL OUTER JOIN B ON A.ID = B.ID
WHERE A.ID IS NULL OR B.ID IS NULL
Try this:
SELECT COALESCE(A.ID , B.ID) AS ID ,
CASE WHEN A.ID IS NOT NULL AND B.ID IS NULL THEN <tableA results>
WHEN A.ID IS NULL AND B.ID IS NOT NULL THEN <tableB results>
END AS results
FROM A FULL OUTER JOIN B ON A.ID = B.ID
WHERE A.ID IS NULL OR B.ID IS NULL
So this is what I came up with after a little help from Tab.
SELECT ID, SELECT CASE WHEN ID IN (SELECT ID FROM A) THEN 'tableA'
WHEN ID IN (SELECT ID FROM B) THEN 'tableB'
FROM A FULL OUTER JOIN B ON A.ID = B.ID
WHERE A.ID IS NULL OR B.ID IS NULL

Syntax for multiple joins in sql

Working on Oracle: I am attempting to do an inner self join, with a where clause, then take that result and do a left outer join on it:
(select * from table1 A
inner join
select * from table1 B
on A.id = B.id
where
A.id is not null and B.id is not null) C
left outer join
select * from table2 D
on C.id = D.id
Somehow I am syntactically challenged and can't make this work. Can't seem to find the right syntax anywhere.
Just the put the where clause at the end. The database will get it right:
select *
from table1 A
inner join table1 B on A.id = B.id
left join table2 D on D.id = A.id
where A.id is not null
In this case, we can take advantage of the logical transitive property for your id column joins and where clause.
Your second join needs to be joined to a query add a select * from at the beginning
select * from (select * from table1 A
inner join
select * from table1 B
on A.id = B.id
where
A.id is not null and B.id is not null) C
left outer join
select * from table2 D
on C.id = D.id