SQL join manager from same table onto a row with their employees - sql

To start, here's a dummy table I've made to show the data I'm working with:
employee
title
division
email
Boss Person
boss
o
bp#email
John Smith
supervisor
a
jos#email
Jane Smith
supervisor
b
jas#email
Leo Messi
employee
a
lm#email
Amanda Kessel
employee
a
ak#email
Derek Jeter
employee
b
dj#email
I want to end up with the following info:
employee
title
division
email
supervisor_name
supervisor_email
Boss Person
boss
o
bp#email
NULL
NULL
John Smith
supervisor
a
jos#email
Boss Person
bp#email
Jane Smith
supervisor
b
jas#email
Boss Person
bp#email
Leo Messi
employee
a
lm#email
John Smith
jos#email
Amanda Kessel
employee
a
ak#email
John Smith
jos#email
Derek Jeter
employee
b
dj#email
Jane Smith
jas#email
I've looked through and tried documentation at:
https://www.sqltutorial.org/sql-self-join/
SQL Server : LEFT JOIN EMPLOYEE MANAGER relationship
One of the big differences here is I don't have any employee or manager id column to work with.
If you're a supervisor for a division, ie John Smith is a supervisor in division a, then you manage all the employees in division a. Meanwhile, all the supervisors answer to the boss in division o, while the boss answers to no one.
Here is the best code I've tried so far:
select e.*, b.employee as supervisor, b.email as supervisor_email
from employees e, employees b
where b.division = e.division
and
b.title like '%supervisor%'
This got me close, it returned:
employee
title
division
email
supervisor_name
supervisor_email
John Smith
supervisor
a
jos#email
John Smith
jos#email
Jane Smith
supervisor
b
jas#email
Jane Smith
jas#email
Leo Messi
employee
a
lm#email
John Smith
jos#email
Amanda Kessel
employee
a
ak#email
John Smith
jos#email
Derek Jeter
employee
b
dj#email
Jane Smith
jas#email
So, it got the employee info right, but left out the Boss record and placed the supervisors as their own supervisor. I think I need some kind of case or if statement here, but I'm not sure.
Please let me know if this makes sense or if any further clarification is needed.

You could try using a LEFT JOIN and work with two conditions:
when division is the same and we're dealing with the relationship employee < supervisor
when the relationship is supervisor < boss
Here's how I did it:
SELECT t1.*,
t2.employee,
t2.email
FROM tab t1
LEFT JOIN tab t2
ON (t1.division = t2.division AND
t2.title = 'supervisor' AND
t1.title = 'employee')
OR (t2.title = 'boss' AND
t1.title = 'supervisor')
You'll find an SQL fiddle here.

If you want to update the current table (if columns are available), you can do the following (more or less the same as #lemon) :
UPDATE testing t1 JOIN testing t2 ON t2.`division`=t1.division OR t2.division="o" SET
t1.supervisor_name=t2.`employee`, t1.supervisor_email=t2.email
WHERE (CASE
WHEN t1.`title`="employee" THEN t2.title="supervisor"
WHEN t1.`title`="supervisor" THEN t2.title="boss"
END);
SELECT * FROM testing;

Related

How to join two tables with three pairs

I have two tables that I want to combine (join) in SQL.
Table 1 Persons:
Person _Id
First_name
Last_name
135790
John
Smith
246801
Lucas
Williams
054953
George
Johnson
460235
Adam
White
Table 2 Loans:
Borrower_Id
resident1_id
resident2_id
135790
246801
054953
460235
054953
135790
054953
246801
135790
The expected result:
Borrower_FN
Borrower_LN
resident1_FN
resident1_LN
resident2_FN
resident1_LN
John
Smith
Lucas
Williams
George
Johnson
Adam
White
George
Johnson
John
Smith
George
Johnson
Lucas
Williams
John
Smith
How can I join it?
This is a way you can achieve the result:
select p.First_name as Borrower_FN, p.Last_name as Borrower_LN,
p2.First_name as resident1_FN, p2.Last_name as resident1_LN,
p3.First_name as resident2_FN, p3.Last_name as resident2_LN
from Loans l
inner join Persons p on p.Person_id = l.Borrower_id
inner join Persons p2 on p2.Person_id = l.resident1_id
inner join Persons p3 on p3.Person_id = l.resident2_id

oracle exercise question in my data using 2 table information

person
name home st
JAMES LA L1
MIKE BOSTON B1
ANTON LA L1
LEE NY N1
BROWN NY N2
mentor
name m_name
JAMES ANTON
MIKE (null)
ANTON (null)
LEE BROWN
BROWN (null)
I want to get information from people who live in the same st and cities as mentors.
In the example I gave, it is JAMES who meets that condition.
How could I get that information?..
my version oracle11g
This sounds like two joins:
select pn.name
from mentor m join
person pn
on pn.name = m.name join
person pm
on pm.name = m.m_name
where pn.street = pm.street and pn.city = pm.city;

How to make a DISTINCT CONCAT statement?

New SQL developer here, how do I make a DISTINCT CONCAT statement?
Here is my statement without the DISTINCT key:
COLUMN Employee FORMAT a25;
SELECT CONCAT(CONCAT(EMPLOYEEFNAME, ' '), EMPLOYEELNAME) AS "Employee", JOBTITLE "Job Title"
FROM Employee
ORDER BY EMPLOYEEFNAME;
Here is it's output:
Employee Job Title
------------------------- -------------------------
Bill Murray Cable Installer
Bill Murray Cable Installer
Bob Smith Project Manager
Bob Smith Project Manager
Frank Herbert Network Specilist
Henry Jones Technical Support
Homer Simpson Programmer
Jane Doe Programmer
Jane Doe Programmer
Jane Doe Programmer
Jane Fonda Project Manager
John Jameson Cable Installer
John Jameson Cable Installer
John Carpenter Technical Support
John Carpenter Technical Support
John Jameson Cable Installer
John Carpenter Technical Support
John Carpenter Technical Support
Kathy Smith Network Specilist
Mary Jane Project Manager
Mary Jane Project Manager
21 rows selected
If I were to use the DISTINCT key I should only have 11 rows selected, however
if I use SELECT DISTINCT CONCAT I get an error.
One option is to use GROUP BY:
SELECT CONCAT(CONCAT(EMPLOYEEFNAME, ' '), EMPLOYEELNAME) AS "Employee",
JOBTITLE AS "Job Title"
FROM Employee
GROUP BY CONCAT(CONCAT(EMPLOYEEFNAME, ' '), EMPLOYEELNAME),
JOBTITLE
ORDER BY "Employee"
Another option, if you really want to use DISTINCT, would be to subquery your current query:
SELECT DISTINCT t.Employee,
t."Job Title"
FROM
(
SELECT CONCAT(CONCAT(EMPLOYEEFNAME, ' '), EMPLOYEELNAME) AS "Employee",
JOBTITLE AS "Job Title"
FROM Employee
) t

SQL Query: How to select multiple instances of a single item without collapsing into a group?

I'm trying to do with following with an SQL query in Impala. I've got a single data table that has (among other things) two columns with values that intersect multiple times. For example, let's say we have a table with two columns for related names and phone numbers:
Names Phone Numbers
John Smith (123) 456-7890
Rob Johnson (123) 456-7890
Greg Jackson (123) 456-7890
Tom Green (123) 456-7890
Jack Mathis (123) 456-7890
John Smith (234) 567-8901
Rob Johnson (234) 567-8901
Joe Wolf (234) 567-8901
Mike Thomas (234) 567-8901
Jim Moore (234) 567-8901
John Smith (345) 678-9012
Rob Johnson (345) 678-9012
Toby Ellis (345) 678-9012
Sam Wharton (345) 678-9012
Bob Thompson (345) 678-9012
John Smith (456) 789-0123
Rob Johnson (456) 789-0123
Kelly Howe (456) 789-0123
Hank Rehms (456) 789-0123
Jim Fellows (456) 789-0123
What I need to get from this table is a selection of each item from the Name column that has multiple entries from the Phone Numbers column associated with it, like this:
Names Phone Numbers
John Smith (123) 456-7890
John Smith (234) 567-8901
John Smith (345) 678-9012
John Smith (456) 789-0123
Rob Johnson (123) 456-7890
Rob Johnson (234) 567-8901
Rob Johnson (345) 678-9012
Rob Johnson (456) 789-0123
This is the query I've got so far, but it's not quite giving me the results I'm looking for:
SELECT a.name, a.phone_number, b.phone_number, b.count1
FROM databasename a
INNER JOIN (
SELECT phone_number, COUNT(phone_number) as count1
FROM databasename
GROUP BY phone_number
) b
ON a.phone_number = b.phone_number;
Any ideas on how to improve my query to get the results I'm looking for?
Thank you.
Working with your query...
This generates a subset by name of users having more than 1 phone number it then joins back to the entire set based on name returning all phone numbers for users having more than 1 phone number. however if a user has the same phone number listed more than once it would get returned. to eliminate those if needed, add distinct to the count in the inline view.
SELECT a.name, a.phone_number
FROM databasename a
INNER JOIN (
SELECT name, COUNT(phone_number) as count1
FROM databasename
GROUP BY name
having COUNT(phone_number) > 1
) b
on a.name = b.name
Order by a.name, a.phone_Number
One method is to use exists:
select t.*
from tablename t
where exists (select 1 from tablename t2 where t2.name = t.name and t2.phonenumber <> t.phonenumber)
SELECT DISTINCT x.*
FROM my_table x
JOIN my_table y
ON y.name = x.name
AND y.phone <> x.phone;

How to find all the employees under one manager using a subquery? SQL

does anyone know how to create a subquery to find all the employees under one manager? For example if I want to find someone that works on susan jones how would I create the query?
Manager Table:
Employee ID Manager_ID Name Title
1 NULL James Smith CEO
2 1 Ron Johnson Sales Manager
3 2 Fred Hobbs Sales Person
4 1 Susan Jones Support Manager
select employeename,managerid
from manager
where manager_id is not null
group by employeename ,manager_id
Well, supposing the table for employees is simply named Employee and its key is named 'Employee_ID' (like in the Manger table), then you just need to use a simple Join:
SELECT e.* FROM Employee AS e JOIN Manger AS m ON e.Employee_ID=m.Employee_ID WHERE m.Name='Susan Jones'