SQL Unique Values - sql

I have this query that joins 3 table. It appears to be working but I am getting duplicates. How can I remove the duplicates?
SELECT FIRST 100 e.email_id, e.location_id, e.email, l.location_type, p.salutation,
p.fname, p.lname
FROM email e, location l, person p
WHERE e.location_id = l.location_id
AND l.per_id = p.per_id

The simple answer is to add DISTINCT to your query.
SELECT FIRST 100 DISTINCT e.email_id, e.location_id, e.email, l.location_type, p.salutation, p.fname, p.lname
FROM email e, location l, person p
WHERE e.location_id = l.location_id
AND l.per_id = p.per_id

use Distinct
SELECT FIRST 100 Distinct e.email_id, e.location_id,
e.email, l.location_type, p.salutation,
p.fname, p.lname
FROM email e, location l, person p
WHERE e.location_id = l.location_id AND l.per_id = p.per_id

Since you are doing straight inner joins, you only get duplicate entries in the result set if there are duplicate entries in the input tables.
SELECT FIRST 100 e.email_id, e.location_id, e.email, l.location_type, p.salutation,
p.fname, p.lname
FROM email AS e
JOIN location AS l ON e.location_id = l.location_id
JOIN person AS p ON l.per_id = p.per_id
The most likely place for there to be trouble is in the 'location' table. You could establish that with a query such as:
SELECT location_id, per_id, COUNT(*)
FROM location
GROUP BY location_id, per_id
HAVING COUNT(*) > 1;
If this returns any data, then you have a pointer to where the trouble is. You should then examine why you don't have a unique constraint on the combination of location_id, per_id.

Related

List the surnames of bosses who manage at least two employees from the query below

I need to get the surnames of bosses who manage at least two employees from the query below that earn no more than twice the average earnings of ALL people they direct.
I'm stuck here:
SELECT surname from emp k INNER JOIN
(SELECT surname, base_salary
from emp p LEFT JOIN
(select id_team, avg(base_salary) as s, count(*) as c from emp group by id_team)
as o ON(p.id_team = o.id_team)
where p.base_salary between o.s*0.7 and o.s*1.3 and o.c >=2) l ON (k.id_boss = o.id_boss)
having count(k.id_boss) >2 ??? AND k.base_salary < ????
I hope you get my point. Any advices how could I do that?
Here's what the full table looks like:
Based on your query you should just add the proper having clause
having count(k.id_boss) >2 AND k.base_salary < 2*l.s
SELECT k.surname
from emp k
INNER JOIN (
SELECT surname, base_salary, id_boss
from emp p
LEFT JOIN (
select id_team, avg(base_salary) as s, count(*) as c
from emp
group by id_team
) o ON p.id_team = o.id_team
where p.base_salary between o.s*0.7 and o.s*1.3 and o.c >=2
) l ON k.id_boss = o.id_boss
group by k.surname
having count(l.id_boss) >2
AND k.base_salary < 2*l.s

SQL explicit join filter condition

Using this relational schema, patient ID and staff ID are foreign keys with id.staff and pid.patient being unique keys:
staff(ID, fname, lname, role)
patient(pID, pFname, pLname, bdate, address, phone)
appointment(aptID, patientID, staffID, aptDate, aptTime)
procedures(procNum, pName, price)
aptDetail(aptID, procNo)
So say if I wanted to list the names of patients with appointments with a specific staff member, i.e John Smith, how would I do that explicitly?
I've managed implicitly, but I know this is kind of frowned upon, but I can't reach it without using WHERE statements.
Any help would be appreciated, any time I try and use INNER JOIN I seem to hit a wall if it's not a simple join.
Is this the type of query you're looking for?
select distinct pFname, pLname
from patient p
join appointment a on p.pID = a.patientID
join staff s on a.staffID = s.ID
where s.fname = 'John' and s.lname = 'Smith'
You can use inner join
select
a.pID
, a.pFname
, a.pLname
, a.bdate
, a.address
, a.phone
, b.aptDate
, b.aptTime
, c.fname
, c.lname
, c.role
from patient a
INNER JOIN appointment b on b.patientID = a.pID
INNER JOIN staff c on b.staffID = c.ID on concat(fname, ' ', lname ) ='John Smith'
Something like the following should work fine:
SELECT p.*
FROM appointment AS a
INNER JOIN staff AS s ON a.staffID = s.pID
INNER JOIN patient AS p ON a.patientID = p.pID
WHERE s.ID = <yourstaffid>;
select staff.fname, staff.role,
patient.pfname, plname, appoitment.aotdate
from staff, patient, appointment
where patient.pid=appointment.patientId
and staff.id=appointment.staffid

How to find a person and count the number of people they manage?

select count(m.emp_id), m.EMP_ID
from employee e join employee m
on e.SUPERIOR_EMP_ID = m.EMP_ID
group by m.EMP_ID;
I can get m.emp_id to show, but I need m.Name. Any tips?
To also see m.Name, you just need to add m.Name to your SELECT and GROUP BY. That said, I don't think your logic is quite right. You want a COUNT(e.Emp_ID) to get the number of employees per manager:
SELECT COUNT(e.Emp_ID), m.Emp_ID, m.Name
FROM Employee e
INNER JOIN Employee m on e.Superior_Emp_ID = m.Emp_ID
GROUP BY m.Emp_ID, m.Name
If you don't care about seeing the manager's employee ID, you can remove that from your select and simply view the name:
SELECT COUNT(e.Emp_ID), m.Name
FROM Employee e
INNER JOIN Employee m on e.Superior_Emp_ID = m.Emp_ID
GROUP BY m.Name
And maybe give it some aliases so it makes more sense to a reader:
SELECT mng.Name as "Manager", COUNT(emp.Emp_ID) as "Number of Employees"
FROM Employee emp
INNER JOIN Employee mng on emp.Superior_Emp_ID = mng.Emp_ID
GROUP BY mng.Name

trying to join two tables and get the count of how many comments were made about a department

My sql is not working when trying to get the total number of comments that were made by each department.
select * from departments d
COUNT( comments.department_id ) AS total_comments
FROM
d
LEFT JOIN
comments c
ON
( d.id = c.department_id )
GROUP BY
d.id, d.title
comments.department_id = departments.id
UPDATE: I neglected to mention I want to display the results in this manner: departments.title (total_comments)
Example: Maintenance (4)
SOLVED: needed to group it by d.title as well, now GROUP BY is d.id, d.title
SELECT departmentID, COUNT(*)
FROM COMMENTS
GROUP BY departmentID
if you need departments that have no comments:
SELECT d.DepartmentID, Count(c.DepartmentID)
FROM Departments d
LEFT JOIN Comments c on d.departmentid = c.departmentid
GROUP BY d.DepartmentID

database sql join question

i have 2 tables called
Location (id, name)
Person (id, name, location_id)
A person has a location Id which joins these tables . . i would like a SQL query that gives me each location and the count of person table for that id.
i could do something like this and then add up the records in code but i want to find out a way that i only get one row per region with count of people in that region
SELECT l.*, r.id from Location l
inner join Person r
on r.location_id = l.id
order by l.name asc
You want to use aggregates and the GROUP BY clause
SELECT l.id, l.name, count(r.id)
FROM Location l
INNER JOIN Person r on r.location_id = l.id
GROUP BY l.id., l.name
ORDER BY l.name asc
Try:
Select L.Name, Count(*) PersonsCount
From Location L
Join Person P On P.Location_Id = L.Id
Group By L.Name
or if you want to see Locations with zero counts,
Select L.Name, Count(*) PersonsCount
From Location L
Left Join Person P On P.Location_Id = L.Id
Group By L.Name
SELECT lo.name, COUNT(*)
FROM LOCATION lo
JOIN PERSON p ON p.location_id = lo.id
GROUP BY lo.name
ORDER BY lo.name
try this
select count(*), Location.name, Location.id from Location, Person where Person.location_id = Location.id group by Location.id