Double outer Join - sql

I have table A that looks like this
ID AValue
----------------------
3 Tom
5 John
9 Mike
and table B that looks like this
ID BValue
----------------------
2 Nancy
3 Maria
9 Clara
10 Sophia
I am trying to join both tables to get this result
ID AValue BValue
------------------------------
2 <NULL> Nancy
3 Tom Maria
5 John <NULL>
9 Mike Clara
10 <NULL> Sophia
If i try to left outer join I would miss the records that do not have match in A
and If I try the right outer join i would miss the records that do not have match in B
any other way I can use?

what you need is FULL OUTER JOIN
SELECT ID = coalesce(a.ID, b.ID), AValue, BVlaue
FROM TalbleA a FULL OUTER JOIN TableB b
ON a.ID = b.ID

Related

SQL select with three tables and foreign keys

I have three tables :
field:
f_id
f_start
f_end
1
10
20
2
15
25
3
5
10
person :
p_id
p_name
1
Roger
2
John
3
Alicia
affect :
id
fk_field
fk_person
1
2
1
2
1
2
3
3
3
And I would like to select the dates and the names associated to. Like this
p_name
f_start
f_end
Roger
15
25
John
10
20
Alicia
5
10
I'm new to SQL and I don't know if i have to use JOIN or not... Thanks
You must join all 3 tables on their related columns:
SELECT p.p_name, f.f_start, f.f_end
FROM person p
INNER JOIN affect a ON a.fk_person = p.p_id
INNER JOIN field f ON f.f_id = a.fk_field;
Depending on your requirement you may need LEFT instead of INNER joins, but for this sample data the INNER joins will do.

sql oracle get all possible values of a lib table

I am using sql ORACLE
I have a library table:
libid libdescr
1 boss
2 secretary
3 manager
And a table with some info:
id libid descr
1 1 jim
1 2 james
2 1 rony
2 2 fred
2 3 jana
I want to join both, but I have to have all possible values of the library. So my result have to be:
id libid libdescr descr
1 1 bos jim
1 2 secretary james
1 3 manager <null>
2 1 boss rony
2 2 secretary fred
2 3 manager jana
If I do a join
select info.*,lib.libdescr
from info
left join lib
on lib.libid = info.libid
I don't get the row id=1 and libid=3
How can I make sure I have all the possible values?
In your query either you need to use right join or use the below query :
select i.*, l.libdescr from lib l left join info i on l.libid=i.libid;
Use a cross join to generate the rows and a left join to bring in the values from the other table:
select i.id, l.libid, l.libdescr, s.descr
from (select distinct id from someinfo) i cross join
library l left join
someinfo s
on s.id = i.id and s.libid = l.libid;

Create 2 new columns from a query

I am battling with joins and inner joins.
I have 2 tables that look like this:
USERS
-----------------------------------------
ID | fname | lname | div_1_id | div_2_id
-----------------------------------------
1 paul smith 1 2
2 john lip 2 null
3 kim long 1 4
DIVISIONS
------------------
ID | name
------------------
1 estate
2 litigation
3 property
4 civil
DESIRED RESULT (sql query)
--------------------------------------------------
user.ID | fname | lname | div_1_name | div_2_name
--------------------------------------------------
1 paul smith estate litigation
2 john lip litigation
3 kim long estate civil
I would like to create a new table from a MS sql query that looks like the above.
Use LEFT JOIN for this:
SELECT u.ID, u.fname, u.lname
, d1.name as div_1_name
, d2.name as div_2_name
FROM USERS u
LEFT JOIN DIVISIONS d1 ON u.div_1_id = d1.ID
LEFT JOIN DIVISIONS d2 ON u.div_2_id = d2.ID
See this SQLFiddle
Try using sub-query:
select a.ID, a.fname, a.lname,
(select name from DIVISIONS b where b.id=a.div_1_id) div_1_name,
(select name from DIVISIONS b where b.id=a.div_2_id) div_2_name
from
USERS a
Use INNER JOIN
SELECT Users.ID, Users.fname, Users.lname, Divisions.name,Div.name
FROM Users INNER JOIN Divisions ON Users.div_id_1 = Divisions.ID
INNER JOIN Divisions Div ON Users.div_id_1 = Div.ID -- Second join with Divisions Table with Alias.

Using multiple joins (e.g left join)

I would like to know what's the logic for multiple joins (for example below)
SELECT * FROM B returns 100 rows
SELECT B.* FROM B LEFT JOIN C ON B.ID = C.ID returns 120 rows
As I know using left join will returns any matching data from the left table which is B if data are found for both table. But how come when using left join, it returns more data than table B itself?
What am I do wrong or misunderstood here? Any guidance are very appreciated. Thanks in advance.
Let be table B:
id
----
1
2
3
Let be table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Any id from b is matched with ids from c, then id=2 will be matched twice. So a left join on id will return 4 rows even if base table B has 3 rows.
Now look at a more evil example:
Table B
id
----
1
2
2
3
4
table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Every id from b is matched with ids from c, then first id=2 will be matched twice and second id=2 will be matched twice so the result of
select b.id, c.name
from b left join c on (b.id = c.id)
will be
id name
------------
1 John
2 Mary
2 Mary
2 Anne
2 Anne
3 Stef
4 (null)
The id=4 is not matched but appears in the result because is a left join.
Look at the following example :
B = {1,2}
C = {(1,a),(1,b),(1,c),(1,d),(1,e)}
The result of B left join C will be :
1 | a
1 | b
1 | c
1 | d
1 | e
2 | null
The number of rows in the result is definitely larger than rows in B (2).
In general the number of rows in result of B left join C is bounded by B.size + C.size and not only by B.size as you think...
As per your query it do the join to B Table with C and B table is Left Table so it will display all the records of Left table in our case it is B and related from other Table in our Case it is C.

SQL Select values associated with keys from other table

I have a mapping table tableA
key value
-----------
1 "John"
2 "George"
3 "Kate"
4 "loves"
5 "hates"
and another tableB that contains rows based on keys of tableA
col1 col2 col3
------------------
1 5 2
2 4 3
3 4 1
I want to write a selection query which will return rows from table B but replaced with their appropriate values.
e.g. the output has to be:
John | hates | George
George | loves | Kate
Kate | loves | John
Thank you.
SELECT A1.value, A2.value, A3.value
FROM tableB
JOIN tableA as A1 ON tableB.col1 = A1.key
JOIN tableA as A2 ON tableB.col2 = A2.key
JOIN tableA as A3 ON tableB.col3 = A3.key;
You should probably put the last 2 items, 'loves' and 'hates', into a separate table as they represent a different type of data than the other 3.
Here are the tables:
users:
id name
----------
1 John
2 Edward
3 Kate
feelings:
id type
----------
1 love
2 hate
feelings_users:
id user1_id feeling_id user2_id
-----------------------------------
1 1 2 2
2 2 1 3
3 3 1 1
and here's the query:
select `Ua`.`name`, `F`.`type`, `Ub`.`name` from `feelings_users` as `X`
left join `users` as `Ua` on `X`.`user1_id` = `Ua`.`id`
left join `feelings` as `F` on `X`.`feeling_id` = `F`.`id`
left join `users` as `Ub` on `X`.`user2_id` = `Ub`.`id`
and it will output:
name type name
--------------------
John hate Edward
Edward love Kate
Kate love John