Trouble retrieving an attribute in SQL query - sql

I have the following relational schema.
EMPLOYEE(Fname, Lname, Ssn, Salary, Dno)
DEPARTMENT(Dname, Dnumber, Mgr_ssn)
For each department, I would like to retrieve the department number, manager first name and the departments average salary.
Below is my attempt. I get the department number and average salary but I can't understand how to retrieve the department manager name without filtering rows which would change the value of the average salary.
SELECT D.Dnumber, AVG(E.Salary)
FROM EMPLOYEE E JOIN DEPARTMENT D ON E.Dno = D.Dnumber
GROUP BY D.Dnumber
How do I retrieve the manager first name within this query?

Presumably, the link to the manager is through the SSN. To me, it is a bad idea to use PII (personally identifiable information) for such a purpose.
In any case, you need two joins to get the first name, so you are half-way there:
select d.dnumber, avg(e.salary), em.fname
from employee e join
department d
on e.dno = d.dnumber left join
employee em
on e.ssn = em.mgr_ssn
group by d.dnumber, em.fname;

Related

practice sql explanation

http://studybyyourself.com/seminar/sql/exercises/8-3/?lang=en
Please provide data about all employees whose salary is higher or equal to the average salary of employees working in the same department (regardless if employees have left the company or not). Required attributes are last name, first name, salary and department name.
SELECT emp.Last_name, emp.First_name, emp.Salary, D.Name
FROM Employee AS emp
INNER JOIN Department AS D ON emp.Department_id = D.ID
WHERE emp.Salary >=
(
SELECT AVG(e.Salary)
FROM Employee AS e
GROUP BY e.Department_id
HAVING e.Department_id = emp.Department_id
)
Can anyone please help explain the solution? Specifically, what does the 'having' clause do in this case that allows the sub-query to work? I get stuck up until that point without the having clause and I expectedly get the 'subquery returns more than 1 row' error but I am not sure how the having clause is fixing the problem.

How get the right information from these tables

I am trying to get a list of all the employee names and their managers and I cannot figure out how to do it. I have attached the relational model.
In DEPT we know the department number (dept_nbr) which is attached to EMPLOYEE through emp_dept and we know the department manager (dept_mgr) which is attached to EMPLOYEE through emp_nbr
select
mgr.emp_nbr ManagerID,
emp.emp_nbr EmployeeID,
emp.emp_lname, emp.emp_fname,
mgr.emp_lname as mgr_lname, mgr.emp_fname as mgr_fname
from
dept
inner join employee as mgr on dept.dept_mgr = mgr.emp_nbr
inner join employee as emp on dept.dept_nbr = emp.emp_dept

How to select departments with no female employees

The schema is as follows:
Employee: Fname, Lname, Ssn, Sex, Dno
Department: Dname, Dnumber, Mgr_ssn
Dnumber is the primary key of department, Ssn is the primary key of employee.
Dno is a foreign key referencing Dnumber.
I tried approaching the problem with this query:
SELECT Dnumber, count(ssn) from DEPARTMENT
INNER JOIN Employee
ON Dno = Dnumber
WHERE sex = ALL('M')
GROUP BY Dnumber
I thought the use of ALL would select only departments with all male employees, where the count would then be applied, however it is selecting all departments with male employees and then counting them.
I'm on the right tracks, and seems like I'm overlooking something trivial, but have tried looking up similar questions but have found no information.
Any pointers toward similar questions or advice on where i'm misstepping would be great.
This just screams "not exists":
select d.*
from department d
where not exists (select 1 from employee where d.dnumber = e.dno and d.sex = 'F');
Incidentally, assuming that all non-females are male would not work in many databases.
Your have multiple missteps in your query. First, ALL() applies to the list of values in the subquery. It doesn't have anything to do with the outer query. Second, it is filtering out all the females in the WHERE. That is fine if you want to count the numbers, but it give you nothing to determine if there are any females.
You could use HAVING (assuming that e.sex is defined as NOT NULL):
SELECT d.dnumber, d.dname
FROM department d
JOIN employee e
ON e.dno = d.dnumber
GROUP BY d.dnumber, d.name
HAVING COUNT(CASE WHEN e.sex = 'F' THEN 1 END) = 0;

Get employees who worked in more than one department with SQL query

I'm trying to figure out a query which shows the names of the employees who worked in more than 2 departments along with their wage and contact details. I have two tables employees and department. Both of these having the EmployeeName field. I know we have to use the Count function but don't really know how to create the query.
here the tablename and Fields:
Employee (employeeName, wage, contactNo)
Department (employeeName, departmentNo, hours, startDate)
You SQL query would be the following
SELECT e.employeeName, count(departmentNo) FROM Employee e
INNER JOIN Department d ON e.employeeName=d.employeeName
GROUP BY e.employeeName
HAVING COUNT(departmentNo)>2
you can use following query:
SELECT e.employeeName, count(d.departmentname)
FROM Employee e, Department d
where e.deptid=d.deptid
GROUP BY e.employeeName
HAVING COUNT(e.deptid)>=2

find the link in tables sql exercise

so I'm stuck on this question where it says:
write a query to retrieve a list of ALL departments in alphabetical order containing the columns DEPARTMENT_ID , DEPARTMENT_NAME , LAST_NAME , FIRST_NAME where last_name and first_name are the name of the Manager of the Department wherever there is one.
I'm have the HR database using the departments, employees table what i have written so far is:
select department_id, department_name, e.last_name, e.first_name
from departments d, employees e
where e.department_id=d.department_id
and d.department_id=e.department_id
and d.manager_id=e.manager_id
having department_name = '%Manager%';
yet i can't figure it out, any tips will help thanks!
A having clause relates to a group by. Where you have no group by, there is no meaning for a having clause.
You just need your join to get the record in the employees table for the manager.
select department_id, department_name, e.last_name, e.first_name
from departments d, employees e
where d.manager_id=e.id
Better is to use the newer join syntax,
select dept.department_id, dept.department_name, emp.last_name, emp.first_name
from departments dept
inner join employees emp on dept.manager_id = emp.id
You don't need conditions for e.department_id=d.department_id and d.department_id=e.department_id, (for one thing these are redundant, so you would only need one if they were needed) because the employees.department_id field refers to the department the employee is in, and what you want is the manager employee record for the department. The manager employee record for the department is represented as the foreign key to the primary key of the employee table.
this might help you...
`select e.first_name,e.last_name,d.department_id ,d.department_name from employees e,departmets d where d.manager_id=e.employee_id order by d.department_name;`