How to join/fill null values using second table while keeping other values intact? - sql

How do I fill the null values in Table A using values from Table B while keeping all other columns/rows intact?
Table A
name
dept
job
jon
null
analyst
mary
null
supervisor
lucy
null
actuary
mark
retail
manager
cindy
retail
sales
Table B
name
dept
job
jon
hr
null
mary
hr
null
lucy
finance
null
attempts to use joins has incorrect results due to having to select which columns show in final table. ex:
SELECT a.name, b.dept, a.job
FROM table_a AS a
LEFT JOIN table_b AS b
ON a.name=b.name
will show
name
dept
job
jon
hr
analyst
mary
hr
supervisor
lucy
finance
actuary
mark
null
manager
cindy
null
sales
I've tried out different types of joins, but can't seem to figure it out. Thanks in advance!

Use COALESCE() to combine two values that could be null.
For example:
SELECT a.name,
coalesce(a.dept, b.dept) as dept,
coalesce(a.job, b.job) as job
FROM table_a AS a
LEFT JOIN table_b AS b
ON a.name=b.name

Related

Need help fetching data from DB2

S.no
emp_id
emp_name
Dept
1
100
John
Sales
2
100
John
Accounts
3
200
Mike
Sales
4
300
Mark
Sales
5
300
Mark
Accounts
6
400
Tom
Sales
I need to pull all the emp_id who are linked ONLY to Sales Dept and ignore the ones that are in both Sales and Accounts. I am using DB2 z/os. Any suggestions would be helpful? Thanks in advance.
An anti-join will produce the result you want.
For example:
select s.*
from employee s
left join employee a on a.emp_id = s.emp_id and a.dept = 'Accounts'
where s.dept = 'Sales' and a.emp_id is null
For good performance you can try adding the index:
create index ix1 on employee (emp_id, dept);

SQL Join on Like Operator

I know this question has been asked a couple of times and i've tried to use the solution for my problem. Unfortunately it did not get me the output i wanted. I need to update ID column in one table by joining it to another table where the joining column does not have exact value.
TableA TableB
EmpNo EmpName ID EmpNo EmpName ID TermDate
101 John Doe Null 250termed_101 John Doe 250 11-15-2018
102 Jane Doe Null 251termed_102 Jane Doe 251 02-25-2019
101 Bryan Adams Null 252termed_101 Bryan Adams 252 03-12-2020
Here's what i tried but was unable to get the required output because the below query is giving me duplicates:
select *
from TableA as A left join
TableB as B
on B.EmpNo like '%' + A.EmpNo + '%' and A.EmpNo is not null
Output Required:
EmpNo EmpName ID
101 John Doe 250
102 Jane Doe 251
101 Bryan Adams 252
I need to populate ID column from TableB into TableA by joining these 2 tables on EmpNo. For the first record, John Doe is terminated on 11-15-2018 and his employee number is assigned to Bryan Adams with unique ID. I need to populate the ID column from TableB into Table A for the corresponding employee who had that number at the time.
Thanks in advance
If your problem is truly that you're getting duplicates that you don't want, you can throw a DISTINCT in. But your problem is in the data: Bryan Adams and John Doe both have employee numbers of 101, so they look duplicated when you join to TableB.
This SQL Fiddle might help you: http://sqlfiddle.com/#!18/f30476/10
You seem on the right path, the update statement should look like the following, also notice how I am making the like comparison more accurate:
update A SET
ID = B.ID
from
TableA as A
left join TableB as B on
B.EmpNo like '%_' + A.EmpNo and
A.EmpNo is not null;
that will break when you have 101 and 1101 or 2101, so it's not a good match, so let's revisit:
update A SET
ID = B.ID
from
TableA as A
inner join TableB as B on
RIGHT(B.EmpNo, len(B.EmpNo) - charindex('_', B.EmpNo)) = A.EmpNo
A.EmpNo is not null and --you don't need this,
charindex('_', B.EmpNo) > 0;--needed, otherwise you get string errors

How to inner join same table with different conditions?

I need to get contact information where employee id is null and not null. How do I join the same table with these different conditions. I need the information to populate a report with both employee information and person accompanied them to a event. Here is the query I have so far.
select events.id, (persons.firstname+' '+ persons.lastname) as employee
from events
inner join eventscontacts on events.id = eventcontacts.events_id
inner join contacts on eventcontacts.contact_id = contacts.id
inner join persons on contacts.person_id = person.id
Eventcontacts table
Id ContactType_id contact_id event_id
1 1 1 300
2 2 3 300
Contact type is 1 for employee and 2 for non emplopyees
contacts table
Id person_id employee_id
1 100 200
2 101 201
3 102 NULL
4 103 202
5 104 203
Person table
Id firstname lastname
100 John Stewart
101 Greg Larry
102 Kim Hans
103 Gloria June
104 Dan Duke
Result table
ID employee accompany
300 John Stewart Kim Hans
right now, I have information of all the employees for the event. I want the people who accompanied these person for the events. Their employee id is null in the contacts table. How do I join the contacts table again here?
An inner join will return only the rows that exist in both tables, where it seems like you want all the rows from the contacts table including the rows that don't match due to them lacking an employee id.
If you use an outer join, it will return rows that exist in contacts AND in events like an inner join but ALSO rows that ONLY exist in events and rows that ONLY exist in contacts.
In the case that I am explaining this poorly, I recommend you read this to help explain:
https://mode.com/sql-tutorial/sql-outer-joins/
If you can successfully use an outer join you will get all the visitors in one table regardless of having an id or not.

Querying 100k records to 5 records

I have a requirement in such a way that it should join two tables with more than 100k records in one table and just 5 records in another table as shown below
Employee Dept Result
id Name deptid deptid Name Name deptid Name
1 Jane 1 1 Science Jane 1 Science
2 Jack 2 2 Maths Dane 1 Science
3 Dane 1 3 Biology Jack 2 Maths
4 Drack 3 4 Social Drack 3 Biology
5 Drim 5 Zoology Kery 4 Social
6 Drum 5 Drum 5 Zoology
7 Krack
8 Kery 4
.
.
100k
Which join need to be used to get the query in an better way to perform to get the result as shown.
I just want the query to join with other table from employee table only which has dept which i thought of below query but wanted to know is there any better way to do it.
Select e.name,d.deptid,d.Name from
(Select deptid,Name from Employee where deptid IS NOT NULL) A
and dept d where A.deptid=d.deptid;
Firstly not sure why you are performing your query the way you are. Should be more like
SELECT A.name, D.deptid,D.Name
FROM Employee A
INNER JOIN dept D
ON A.deptid = D.deptid
No need of the IS NOT NULL statement.
If this is a ONE TIME or OCCASIONAL thing and performance is key (not a permanent query in your DB) you can leave out the join altogether and do it using CASE:
SELECT
A.name, A.deptid,
CASE
WHEN A.deptid = 1 THEN "Science"
WHEN A.deptid = 2 THEN "Maths"
...[etc for the other 3 departments]...
END as Name
FROM Employee A
If this is to be permanent and performance is key, simply try applying an INDEX on the foreign key deptid in the Employee table and use my first query above.

Should I Use a Self-Join

If I have a table...
ID Name Manager
0 Joe Sue
1 Jake Tom
0 Joe Tom
2 Larry Red
2 Larry Paul
1 Jake Paul
I want the output to be....
ID Name Manager1 Manager2
0 Joe Sue Tom
1 Jake Tom Paul
2 Larry Red Paul
Thanks...
If I have understood your request properly, yes, something like would produce the results you are looking for.
SELECT
t1.Name Name,
t1.Manager Manager1,
t2.Manager Manager2
FROM
Table t1
inner join Table t2 on t1.Manager = t2.Name
Of course a foreign key back to the index column would be preferential to strong comparisons for performance.
Yeah, if your table was called 'Managers':
SELECT Mgr1.ID,Mgr1.Name,Mgr1.Manager,Mgr2.Manager
FROM Managers AS Mgr1
LEFT JOIN Managers AS Mgr2
ON Mgr1.ID=Mgr2.ID
If your keeping the tables a join would be best.
If you hate joins, you could combine the max and min managers, and even then it would work if there is always 2 managers and they can't have the same name.
The below should work if I remember how to join up 2 queries correctly. but i would advise to see if it is possible to rework your table, have a separate table linking people to each other in a manager employee relation.
SELECT DISTINCT
F.ID, F.Name, S.Manager, F.Manager
FROM
(SELECT
ID, Name, MIN(manager) manager
FROM Managers
GROUP BY ID, Name) F,
(SELECT
ID, Name, MAX(manager) manager
FROM Managers
GROUP BY ID, Name) S
WHERE
F.ID = S.ID
AND S.Manager <> F.Manager
AND F.ID < S.ID