Here's my question. I'm just not even sure where I should start.
List the first name, last name, and title of each employee, as well as the first name, lastname, and title of their supervisor; employees without supervisors should have null for theirsupervisor values. Alias only the columns for the supervisor toSuperFirst,SuperLast,andSuperTitle; columns should be ordered asFirstName,LastName,Title,SuperFirst,SuperLast, andSuperTitle.
Here's the ER Diagram:
What is the question here? Please provide a clear question for us to work with.
Example Below for reference.
LEFT Join return all Employees all results that have a supervisor and ones that don't. The ones that don't would have a NULL value in the "S.*" columns. That should accomplish what you need.
SELECT FirstName, LastName, Title, S.FirstName AS SuperFirst, S.LastName AS SupertLast, S.Title AS SuperTitle
FROM dbo.Employee E
LEFT JOIN dbo.Employee S ON E.ReportsTo = S.EmployeeID
You are looking for a self-join on Employee Table as below as it references itself.
SELECT emp.FirstName
,emp.LastName
,emp.Title
,super.FirstName as SuperFirst
,super.LastName as SuperLast
,super.Title as SuperTitle
FROM employee emp
LEFT JOIN employee super ON emp.reportsto = super.EmployeeId
ORDER BY 1
,2
,3
,4
,5
,6;
Left join will put null in Supervisor columns if no matching values are retrieved.
Like mentioned before, when LEFT JOIN you should be able get NULL when there is no match. This code should work!
SELECT Employee.FirstName, Employee.LastName, Employee.Title, Emp.FirstName AS SuperFirst, Emp.LastName AS SuperLast, Emp.Title AS SupperTitle
FROM Employee LEFT JOIN Employee AS Emp ON Employee.ReportsTo = EmployeeTwo.EmployeeId
Related
The code below is completely wrong and does not work at all. Im basically trying to look through my tables and compile a list of DeptName and the total student number for a department where a department has more than 40 students.
Im confused about joins in general and if someone could explain and show where im going wrong. im sure there is also other problems so any help with them would help
So basically one department is connected to one module, and a student is enrolled in a module. A student cannot take a module outside of their department. So each student should have one module that connects to one department
All of the ID fields in other tables are foreign keys as you can guess and changing the tables is not what I want to do here I just want to do this query as this stands
Relevant tables columns
Table Department DeptID, DeptName, Faculty, Address
Table Modules ModuleID, ModuleName, DeptID, Programme
Table Students StudentID,StudentName,DoB,Address,StudyType,`
Table Enrolments EID,StudentID,ModuleID,Semester,Year
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students' FROM Department LEFT JOIN Module ON Department.DeptID= Module.DeptID LEFT JOIN Enrolment ON Module.ModuleID= Enrolment.StudentID LEFT JOIN Student.StudentID
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
I have not included every table here as there are quite a lot.
But unless i've got this completely wrong you don't need to access a ModuleID in a staff table for the module they teach or something not relevant to this at all. As no student or Dept details are in there.
If that is the case i will fix it very quickly.
SELECT Department.DeptName, COUNT(Student.StudentID) AS 'No of Students'
FROM Department
LEFT JOIN Module
ON Department.DeptID= Module.DeptID
LEFT JOIN Enrolment
-- problem #1:
ON Module.ModuleID= Enrolment.StudentID
-- problem #2:
LEFT JOIN Student.StudentID
-- problem #3:
GROUP BY(Department.DeptID)
HAVING COUNT(Student.StudentID)>=40
You're joining these two tables using the wrong field. Generally when the modeling is done correctly, you should use USING instead of ON for joins
The right side of any JOIN operator has to be a table, not a column.
You have to group by every column in the select clause that is not part of an aggregate function like COUNT. I recommend that you select the DeptID instead of the name, then use the result of this query to look up the name in a subsequent select.
Note : Following code is untested.
WITH bigDepts AS (
SELECT DeptId, COUNT(StudentID) AS StudentCount
FROM Department
JOIN Module
USING ( DeptID )
JOIN Enrolment
USING ( ModuleID )
JOIN Student
USING ( StudentID )
GROUP BY DeptID
HAVING COUNT(StudentID)>=40
)
SELECT DeptID, DeptName, StudentCount
FROM Department
JOIN bigDepts
USING ( DeptID )
Instead of left join you need to use inner join since you need to select related rows only from those three tables.
Groupy by and having clause seems fine. Since you need departments with more than 40 students instead of >= please use COUNT(e.StudentID)>40
SELECT d.DeptName, COUNT(e.StudentID) AS 'No of Students' FROM Department d INNER JOIN Module m ON d.DeptID= m.DeptID inner JOIN Enrolment e ON m.ModuleID= e.StudentID LEFT JOIN Student.StudentID
GROUP BY(d.DeptName)
HAVING COUNT(e.StudentID)>40
So your join clause was a bit iffy to students as you wrote it, and presumably these should all be inner joins.
I've reformatted your query using aliases to make it easier to read.
Since you're counting the number of rows per DeptName you can simply do count(*), likewise in your having you are after counts greater than 40 only. Without seeing your schemas and data it's not possible to know if you might have duplicate Students, if that's the case and you want distinct students count can amend to count(distinct s.studentId)
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Enrolment e on e.StudentId=m.ModuleId
join Students s on s.StudentId=e.studentId
group by(d.DeptName)
having Count(*)>40
Also, looking at your join conditions, is the Enrolement table relevant?
select d.DeptName, Count(*) as 'No of Students'
from Department d
join Module m on m.DeptId=d.DeptId
join Students s on s.StudentId=m.moduleId
group by(d.DeptName)
having Count(*)>40
I've been searching for answers awhile on here, but I'm just ending up going in circles.
anyways, assuming I have two tables:
Employee with the attributes first_name, last_name, middle_initial, and ESSN
and
dependents with the attributes essn, dependent_name and relationship
I want to simply list the names of all department managers who have no dependents.
The code i'm trying to use works if the != is set to =, and gives me the matching results.
What do I to pull up the results that do not match?
select employee.first_name, employee.middle_initial, employee.last_name
from employee join dependent on employee.essn = dependent.essn
where employee.essn != dependent.essn
group by employee.first_name;
i also attempted to use != with the ESSN of the department managers, but I ran into the same problem.
It can be achieved much easier:
select first_name from employee where essn not in (select essn from dependent);
I would use left join where dependent.essn is null
select employee.first_name, employee.middle_initial, employee.last_name
from employee
left join dependent
on employee.essn = dependent.essn
where dependent.essn is null
My bad..just noticed this is mysql.. I assume it would be the same as mssql
I have been asked this question in an interview. I have tried so hard, but unfortunately was not able to get it right.can anybody help me with this?
Retrieve the last name, first name, dept name of that employee using these tables.I am writing down the tables and columns.however, i am not writing that dummy data.
Employee- (id, last name, first name, DOB, SSN) and some other columns(not useful).
Dept - (D_id, dept name)
Emp_Dept - (id, D_id)
You can try this solution for your problem :
Query :
SELECT E.last_name, E.first_name, D.dept_name
FROM Employee AS E
-- Get employee dept
INNER JOIN Emp_Dept AS ED
ON ED.id = E.id
-- get dept data
INNER JOIN Dept AS D
ON D.id = ED.D_id
I hope it will help you.
But this query doesn't return value of employee without dept. If this is necessary you should use LEFT JOIN instead of INNER JOIN
Here's my query:
select project_number, concat(first_name,' ',last_name) as employee_name, department_name
from ex.projects p right join employees e
On e.employee_id = p.employee_id
right join departments d
on d.department_number = e.department_number
order by department_name
How can I switch the two people names? Need "cindy smith' to be on bottom of "Ralph simonian" and "Robert Aaronsen" to be on top "Ralph simonian"
I would do this using left join rather than right join. Reading left join is easier: keep everything in the first table and then matching rows in the rest. This is easier to read than . . . "wait til you see what is in the last table to see what the rows are going to be."
But leaving your method, you need an order by:
select project_number, concat(first_name, ' ', last_name) as employee_name,
department_name
from ex.projects p right join
employees e
On e.employee_id = p.employee_id right join
departments d
on d.department_number = e.department_number
order by department_name, last_name;
based on your sample, you only need to add in the order clause the project number and employee name in descending order
order by department_name, project_number, employee_name desc
Lets say I have the following database model:
And the question is as follows:
List ALL department names and the total number of employees in the department. The total number of employees column should be renamed as "total_emps". Order the list from the department with the least number of employees to the most number of employees. Note: You need to include a department in the list even when the department does not currently have any employee assigned to it.
This was my attempt:
SELECT Department.deptname
(SELECT COUNT(*)
FROM Department
WHERE Department.empno = Employee.empno ) AS total_emps
FROM Department
I'm pretty sure my solution is not correct as it won't include departments with no employees. How do you use a left inner join to solve this problem?
The query as you were trying to write it is:
(table creates modified from shree.pat18's sqlfiddle to this sqlfiddle)
create table department (deptno int, deptname varchar(20));
insert into department values (1, 'a'),(2, 'b'),(3, 'c');
create table employee (empno int, deptno int);
insert into employee values (1,1),(2,1),(3,3);
SELECT d.deptname,
(SELECT COUNT(*)
FROM EMPLOYEE e
WHERE d.deptno = e.deptno ) AS total_emps
FROM DEPARTMENT d
ORDER BY total_emps ASC;
(You were counting from DEPARTMENT instead of EMPLOYEE and comparing empno instead of deptno. And you left out a comma.)
(You were asked for every department's name and employee count so this returns that. In practice we would include a presumably unique deptno if deptname was not unique.)
I'm pretty sure my solution is not correct as it won't include
departments with no employees.
Even your answer's version of the query (with the missing comma added) has an outer select that returns a count for every department no matter what the subselect returns. So I don't know why/how you thought it wouldn't.
If you want to use LEFT (OUTER) JOIN then the DEPARTMENT rows with no employees get extended by NULL. But COUNT of a column only counts non-NULL rows.
SELECT d.deptname, COUNT(e.empno) AS total_emps
FROM DEPARTMENT d
LEFT JOIN EMPLOYEE e
ON d.deptno = e.deptno
GROUP BY d.deptno
ORDER BY total_emps ASC;
(Nb the LEFT JOIN version uses more concepts: LEFT JOIN extending by NULL, GROUP BY, and COUNT's NULL behaviour for non-*.)
First off, it's a left outer join. Now, for your query, you want to join the 2 tables based on deptno, then also group by deptno (or deptname, since that is as likely to be unique) to ensure that any aggregation we do is done for each unique department in the table. Finally, the counting is done with the count function, leading to this query:
select d.deptname, count(e.empno) as total_emps
from department d
left join employee e on d.deptno = e.deptno
group by d.deptname
SQLFiddle
Note that since we want all records from department regardless of whether there are matching records in employee or not, department must appear at the left side of the join. We could have done the same thing using a right outer join by swapping the positions of the 2 tables in the join.