Only return results from first table with two joins - sql

I have 3 tables. I need to get lastname, firstname, and employee number from the first table and name from another table.
In order for me to get the name on table s there needs to be a match between the slsrep columns on table s and table sw.
The issues is that I only want to return the rows from the first table (p). There is only 700 records in the first table but it is pulling 900.
Basically, I just want to look at each row in the table p and match the name from table s.
This is what I currently have:
SELECT p.LastName,
p.FirstName,
p.EmpNo,
s.Name
FROM PDDA..PhoneDirectory p
LEFT OUTER JOIN nxtsql..swsmsn sw
ON p.EmpNo = sw.EmpNo
JOIN NxtSQL..SMSN s
ON sw.slsrep = s.slsrep
WHERE sw.statustype = 1
ORDER BY
p.LastName

There are lots of ways to do this. One is to use a sub-select to get s.Name:
SELECT p.LastName, p.FirstName, p.EmpNo, (
SELECT TOP 1 s.Name
FROM NxtSQL..SMSN s
INNER JOIN nxtsql..swsmsn sw
ON sw.slsrep = s.slsrep
WHERE p.EmpNo = sw.EmpNo
AND sw.statustype = 1
) AS Name
FROM PDDA..PhoneDirectory p
ORDER By p.LastName

Related

SELECT and JOIN to return only one row for each employee

I have a user table that stores the employeeId, lastName, firstName, department, hire date and mostRecentLogin.
I have another table that stores the employeeId, emailAddress.
The emailAddress table can have multiple rows for an employee if they have multiple email addresses.
I'm trying to return results that only show one row for each employee. I don't care which email address, just as long as it only picks one.
But all the queries I've tried always return all possible rows.
Here is my most recent attempt:
select *
from EmployeeInfo i
left join EmployeeEmail e ON i.employeeId = e.employeeId
where i.hireDate = 2015
and employeeId IN (
SELECT MIN(employeeId)
FROM EmployeeInfo
GROUP BY employeeId
)
But then again, this returns all possible rows.
Is there a way to get this to work?
Use a sub-query instead of a join:
select *
, (select top 1 E.EmailAddress from EmplyeeEmail E where E.employeeId = I.employeeId)
from EmployeeInfo I
where I.hireDate = 2015;
Note: If you change your mind and decide you do have a preference as to which email address is returned then just add an order by to the sub-query - otherwise it is truly unknown which one you will get.
This should work.
SELECT *
FROM EmployeeInfo
Left JOIN EmployeeEmail
ON EmployeeInfo.employeeId = EmployeeEmail.employeeId
WHERE EmployeeInfo.hireDate = '2015'
GROUP BY EmployeeInfo.employeeId;

joining a table on 2 fields

I want to pull a person and their supervisor names from a table. The persons table has the supervisor_id and the person_id. The names table has name_id and a Full Name field. If I join Person ON either supervisor_id or person_id, how do I get the other to display as well?
You need to join twice, one for each relationship you have:
SELECT
-- Persons' columns
P.*,
-- Superviser name columns
SN.*,
-- Person name columns
PN.*
FROM
persons AS P
LEFT JOIN names AS SN ON P.supervisor_id = SN.name_id
LEFT JOIN names AS PN ON P.person_id = PN.name_id
Or you can join with an OR clause, but you won't be able to know which record did you join with unless you check with a CASE.
SELECT
-- Persons' columns
P.*,
-- name columns
N.*,
IsSupervisor = CASE WHEN P.supervisor_id = N.name_id THEN 'Yes' ELSE 'No' END
FROM
persons AS P
LEFT JOIN names AS N ON
P.supervisor_id = N.name_id OR
P.person_id = N.name_id
This last approach will display 2 rows as it will match either one or the other on different occasions, not both with the same persons row (as the first example).
A (self)join is what you need:
select p.*, supervisor=ps.name
from Person p join person ps on p.supervisor_id=ps.id

SQL select, 3 tables

How can I use select if I have 3 tables?
Tables:
school_subject(ID_of_subject, workplace, name)
student(ID_of_student, firstName, surname, adress)
writing(ID_of_action, ID_of_sbuject, ID_of_student)
I want to write the student's name and surname (alphabetically) who have workplace=home.
Is this possible? And how to alphabetize?
SELECT s.firstName, s.surname
FROM student S, school_subject P, writing Z
WHERE P.workplace = 'home'
AND P.ID_of_subject = Z.ID_of_subject
AND Z.ID_of_student = s.ID_of_student;
SELECT s.firstName, s.surname
FROM student S INNER JOIN writing Z
ON Z.ID_of_student = s.ID_of_student
INNER JOIN school_subject P
ON P.ID_of_subject = Z.ID_of_subject
WHERE P.workplace = 'home'
ORDER BY S.firstName, S.surname // Sort the list
To order alphabetically the result it is possible to use ORDER BY keyword. So your query becomes:
SELECT DISTINCT S.firstName, S.surname
FROM student S, school_subject P, writing Z
WHERE P.workplace = 'home' AND
P.ID_of_subject = Z.ID_of_subject AND
Z.ID_of_student = S.ID_of_student
ORDER BY S.surname, S.firstName
The DISTINCT keyword is necessary, because in writing table there are eventually more tuples given keys ID_of_subject and ID_of_student.
So this is necessary to avoid repeating firstName and surname many times.
Note that each student is identified by ID_of_student, not by firstName and surname, so as #danjok said use DISTINCT if you only want the name and surname.
If you want to select all students that satisfy your requirement (even if two or more students have the same firstName and surname), you should including ID_of_student on SELECT clause:
SELECT S.ID_of_student, S.firstName, S.surname
FROM student S
INNER JOIN writing W ON W.ID_of_student = S.ID_of_student
INNER JOIN school_subject P ON P.ID_of_subject = W.ID_of_subject
WHERE P.workplace = 'home'
ORDER BY S.firstName asc, S.surname asc

select distinct out of distinct

I have two table one has employees goals and the other has list of employees. i have to match one to another. Seems easy to do. but in the employee table employees can be entered more than once with more than one way of spelling their names. How can I pick only one name for each ID, it really doesn't matter which one I pick.
this is the code i used:
select distinct (etar.EmplKey ), emp.EmplFullName
FROM EmployeeTarget etar
inner join DimEmployee emp on emp.emplkey = etar.emplkey
inner join dimbranch br on br.BranchId = etar.BranchId
where etar.BranchId = 8
this is the results i get:
EmplKey EmplFullName
100260 Ida Patton
101488 Don Sheppard
101488 Donald Sheppard
101489 Teresa Coverdale
103121 Harjinder Aujla
How can I have that Don Sheppard guy listed only once?
The easiest way is to do aggreagtion:
select etar.EmplKey, min(emp.EmplFullName)
FROM EmployeeTarget etar
inner join DimEmployee emp on emp.emplkey = etar.emplkey
inner join dimbranch br on br.BranchId = etar.BranchId
where etar.BranchId = 8
group by etar.EmplKey

SQL Query to get rid of duplicate records [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How Do You Delete Duplicate Records In SQL
I have a table with columns:
FirstName
LastName
AddressLine1
AddressLine2
City
State
For each row, AddressLine1 is different from AddressLine2 value. But there are some duplicates rows, in which AddressLine1 of some records matches with AddressLine2 of some other record.
I want to get rid of such records mentioned above.
This will get all duplicate records:
SELECT P.*
FROM table P INNER JOIN
table S ON P.FirstName = S.FirstName
AND P.LastName = S.LastName
WHERE P.AddressLine1 = S.AddressLine2
If your table had an ID you could write a delete to remove duplicates like this:
DELETE FROM table
WHERE Id IN (
SELECT P.Id
FROM table P INNER JOIN
table S ON P.FirstName = S.FirstName
AND P.LastName = S.LastName
WHERE P.AddressLine1 = S.AddressLine2
)
Join the table to itself
DELETE a
FROM Table a
JOIN Table b
ON a.AddressLine1 = b.AddressLine2
Swap out UNIQUE_IDENTIFIER with some ID's or names or what have you do easily identify in the future. Then you can hand delete as needed. Or modify what is below into an UPDATE or DELETE statement as needed.
SELECT
t1.UNIQUE_IDENTIFIER,
t2.UNIQUE_IDENTIFIER
FROM
table t1,
table t2
WHERE
t1.AddressLine1 = t2.AddressLine2