Bidirectional outer join - sql

Suppose we have a table A:
itemid mark
1 5
2 3
and table B:
itemid mark
1 3
3 5
I want to join A*B on A.itemid=B.itemid both right and left ways. i.e. result:
itemid A.mark B.mark
1 5 3
2 3 NULL
3 NULL 5
Is there a way to do it in one query in MySQL?

It's called a full outer join and it's not supported natively in MySQL, judging from its docs. You can work around this limitation using UNION as described in the comments to the page I linked to.
[edit] Since others posted snippets, here you go. You can see explanation on the linked page.
SELECT *
FROM A LEFT JOIN B ON A.id = B.id
UNION ALL
SELECT *
FROM A RIGHT JOIN B ON A.id = B.id
WHERE A.id IS NULL

Could do with some work but here is some sql
select distinct T.itemid, A.mark as "A.mark", B.mark as "B.mark"
from (select * from A union select * from B) T
left join A on T.itemid = A.itemid
left join B on T.itemid = B.itemid;
This relies on the left join, which returns all the rows in the original table (in this case this is the subselect table T). If there are no matches in the joined table, then it will set the column to NULL.

This works for me on SQL Server:
select isnull(a.id, b.id), a.mark, b.mark
from a
full outer join b on b.id = a.id

Related

Create column that combines two columns by ifelse statementet in SQL

In SQL I am trying to combine create a column id_main2 (after a right join) that is equal the value of column id_main (coming from a) if not NULL and the value of id (coming from b) if id_main is NULL.
Below is the join code followed by the desired output. How can I create this id_main2 column?
SELECT * FROM a
RIGHT JOIN b on a.id = b.id;
id_main id boy id girl id_main2
10 1 Alex 1 Alice 10
11 2 Bruce 2 Brunet 11
NULL NULL NULL 5 Emma 5
NULL NULL NULL 6 Fabia 6
I think you just want coalesce():
select a.*, b.*,
coalesce(a.id_main, b.id)
from b left join
a
on a.id = b.id;
I strongly prefer left join to right join, so I rearranged the tables in the from clause.
You can either use coalesce()
select
coalesce(a.id_main, b.id) as id_main2
from a
right join b on a.id = b.id;
or case when
select
case when a.id is not null then a.id
else b.id end as id_main2
from a
right join b on a.id = b.id;

Joining two tables where id does not equal

I'm struggling getting this query to produce the results I want.
I have:
table1, columns=empid, alt_id
table2, columns=empid, alt_id
I want to get the empid, and alt_id from table 1 where the alt_id does not match the alt_id in table2. They will both have alt_id numbers I just want to get the ones that do not match.
Any ideas?
SELECT * FROM table1
INNER JOIN table2 ON table2.empid = table1.empid AND table2.alt_id <> table1.alt_id
What does that really mean though? Normally when this is asked, it is of the form "I want all rows from A that have no row matching in B and all in B that have no match in A"
Which looks like this:
SELECT * FROM
A
FULL OUTER JOIN
B
ON
a.id = b.id
You'll see a null for any row data where there isn't a matching row on the other side:
A.id
1
2
B.id
1
3
Result of full outer join:
A.id B.id
1 1
2 null
null 3
You, however have asked for A-B join where the IDs aren't equal, which would be the more useless query of:
SELECT * FROM
A
INNER JOIN
B
ON
a.id != b.id
And it would look like:
A.id B.id
1 3
2 1
2 3
You seem to want not exists:
select t1.*
from table1 t1
where not exists (select 1 from table2 t2 where t2.alt_id = t1.alt_id);
It is unclear whether or not you also want to join on empid, so you might really want:
select t1.*
from table1 t1
where not exists (select 1 from table2 t2 where t2.alt_id = t1.alt_id and t2.empid = t1.empid);
A left join will find all records in Table A that do not match those in Table B. Then use a Where filter to find the Nulls from Table B. That will give you all those in Table A that do not have a matching ID in Table B.
Select A.*
from Table A
Left Join
Table B
on a.altid = b.altid
where b.altid is null;
select *
from [Login] L inner join Employee E
on l.EmployeeID = e.EmployeeID
where l.EmployeeID not in (select EmployeeID from Employee)

Ignore rows with NULL join columns in hive query

I have three tables A, B and C. A is having 1 billion records, B is having 10 million records and C is having 5 million records.
My query is like
select *
from tableA a
left outer join tableB b on a.id=b.id
left outer join tableC c on b.id=c.id;
After first join i will be having more than 990 million NULL b.id columns. Now the second join on table C will require all 990 million NULL rows (b.Id) to be processed and this causes one reducer to be loaded for a very long time. Is there a way i can avoid rows with NULL join columns?
We have used rand() for NULL ; so our join condition will be
coalesce(b.id, rand()) = c.id
Thus null values got distributed by its own, but i am wondering why the skewjoin settings didnot help (we have tried coalesce(b.id, 'SomeString') = c.id with skewjoin enable )
Add b.id is not null condition to the ON clause. Depending on your Hive version this may help:
select *
from tableA a
left outer join tableB b on a.id=b.id
left outer join tableC c on b.id=c.id and b.id is not null;
But this is not a problem since 0.14 version as far as I know.
Also you can divide null rows and not null and join only not null rows.
In the first query only null rows selected. Add NULL as col for columns from C table. Then use UNION ALL + select all not null rows:
with a as(
select a.*, b.*
from tableA a
left outer join tableB b on a.id=b.id
)
select a.*, null as c_col1 --add all other columns(from c) as null to get same schema
from a where a.b_id_col is null
UNION ALL
select a.*, c.*
left outer join tableC c on a.b_id_col=c.id
from a where a.b_id_col is not null

SQL - not sure how to join tables

I'm trying to join two tables like this:
Table A
ID Value1
1 A
2 B
3 C
Table B
ID Value2
1 A
3 B
4 C
Result should be:
ID Value1 Value2
1 A A
2 B null
3 C B
4 null C
I.e. join Table A to Table B on ID. If ID doesn't exist in Table A, add the ID from Table B.
The closest I've come is:
SELECT
a.ID, a.Value1, b.Value2
FROM
TableA a
OUTER JOIN
TableB b ON a.ID = b.ID
That gives me the new rows from TableB, but the ID is null.
How can I accomplish this?
You are very close, you just need a little push in the right direction:
SELECT COALESCE(a.ID, B.ID) As ID, a.Value1, b.Value2
FROM TableA a
FULL OUTER JOIN TableB b ON a.ID=b.ID
The COALESCE function returns the first parameter it gets that is not null. since this is a full outer join, a.id will be null on one row and b.id would be null on a different row.
Try this:
SELECT *
FROM TableA A
FULL OUTER JOIN TableB B
ON A.ID = B.ID;
Just a note: you should not name your tables in SQL with spaces in them.
Remember the basic for joining different tables
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;
For your case:
SELECT a.value1, b.value2
FROM TableA a
FULL OUTER JOIN TableB b ON a.ID=b.ID
remember full outer join
The FULL OUTER JOIN keyword returns all rows from the table (tableA) and from the table (tableB) and the FULL OUTER JOIN keyword combines the result of both LEFT and RIGHT joins.

Getting data from one table to another table using join

I have a table name "a"
Id name
1 abc
2 xyz
3 mmm
4 xxx
and Other table name is "b"
Id suId
3 2
3 1
My requirement is get detail from "a" table from "b" table where id=3. Any help?
SELECT a.Id, a.name, b.Id, b.suId FROM b JOIN a ON b.suId = a.Id WHERE b.Id = 3;
I wont recommend join for this kind of scenarios(you want all details from Table A whose ids are in Table B suId column, where Table B id should be 3., Its bad English but hope you got me and may be i got you too.)
SELECT a.name FROM a
WHERE
a.id IN(SELECT b.suId FROM b WHERE b.id = 3);
If you want to use join only then,
SELECT a.name FROM a,b
WHERE a.id = b.suId
AND
b.id = 3;
Simple answer:
SELECT a.Id,a.name FROM a,b
WHERE a.Id=b.suId AND b.Id=3
It will give you the result:
Id Name
1 abc
2 xyz
See result in SQL Fiddle
This should get the job done:
SELECT * FROM table_a a JOIN table_b b ON b.suId = a.Id WHERE b.Id = 3;
You can try this...You can try different JOIN clauses like INNER JOIN, LEFT OUTER JOIN or just simply JOIN etc. You will get different number of rows depending on field connections from 1 table to the other.
SELECT T1.*
FROM a T1
INNER JOIN b T2
ON T1.Id = T2.Id
WHERE T1.Id='3'