How to get column value from "nested relation" in sql - sql

Not sure of the correct phrasing to use here, but here's the case.
I have 3 tables.
Employee
id
name
department_id
1
Jon Doe
2
Department
id
name
office_id
2
Accounting
3
Office
id
name
3
London
Now, getting the employee with department name is straight forward:
select employee.id, employe.name, department.name as department_name, department.office_id
from employee
inner join department on employee.department_id = department.id
How can i also include the office name in the result?

You can use a second inner join for the office:
select employee.id, employe.name, department.name as department_name, department.office_id, office.name as office_name
from employee
inner join department on employee.department_id = department.id
Inner join office on office.id = department.office_id

Related

Query to get employee name and manager name that are from different tables

Employee Table
EmployeeNumber (PK)
PersonID
ReportstoManagerEmployeeNumber (i.e.- the employee number of the employee's manager)
Names Table
PersonID (PK)
FirstName
LastName
I want to display FirstName, LastName, EmployeeNumber, ReportstoManagerEmployeeNumber , Firstname as managerfirstname, LastName as managerlastname
Basically I want to select the first name and last name of the ReportstoManagerEmployeeNumber column
What I have tried:
SELECT n.FirstName, n.LastName, emp.EmployeeNumber,
emp.ReportstoManagerEmployeeNumber, n.firstname as managerfirstname, n.lastname as managerlastname
FROM Names n
INNER JOIN employees emp
ON n.personID = emp.personID
INNER JOIN employees emp2
ON n.personID = emp2.personID
I was thinking a self-join but this won't work as this just selects the names of the employees from the first and second column. I am new to SQL but I believe a subquery or a CTE is required but I am not sure how to set it up.
To clarify-- John Smith has personID = 1 in the Names table but has employeeID = 2 in the employee table.
It is the other way around, you need to join 2 Names tables one for the employee and one for the manager
SELECT
emp.EmployeeNumber,
n.FirstName,
n.LastName,
emp.ReportstoManagerEmployeeNumber,
n1.firstname AS managerfirstname,
n1.lastname AS managerlastname
FROM
employees emp
INNER JOIN
Names n ON n.personID = emp.PersonID
INNER JOIN
employees emp2 ON em2.EmployeeNumber= emp.ReportstoManagerEmployeeNumber
INNEr JOIN
Names n1 ON n1.personID = emp2.personID

Boolean inside SELECT - help needed

I need to write a SQL query to get the department name and the number of female professors in that department even if there aren't any female professors hired there. Please help. Thank you.
STUDENT
id
first_name
last_name
is_female
department_id
DEPARTMENT
id
name
PROFESSOR
id
first_name
last_name
is_female
department_id
This is my query:
SELECT
department.name, COUNT(professor.is_female)
FROM
department, professor
WHERE
department.id = professor.department_id
Not sure why you included the student table but try either this correlated sub-query:
select name, (select count(*) from PROFESSOR where DEPARTMENT.id = PROFESSOR.department_id and is_female = true) as 'count'
from DEPARTMENT
or left-join:
select name, count(*)
from DEPARTMENT
left join PROFESSOR on DEPARTMENT.id = PROFESSOR.department_id and is_female = true
group by 1

How to get the department name in this tutorial sql query?

Following the tutorial on SQL here I want to query the number of employees per department together with the department name.
I tried the following query in that tutorial:
SELECT count(*), dept_name
FROM employees, departments
WHERE employees.dept_id = departments.dept_id
GROUP BY departments.dept_id
but it returns
COUNT(*) dept_name
2 NULL
2 NULL
instead of the expected output
COUNT(*) dept_name
2 Accounting
2 Sales
What am I doing wrong here?
First use JOIN instead of WHERE
Then you group by dept_id to make sure you dont have duplicate name like 2 Sales department or 2 employee with same name.
SELECT departments.dept_id, dept_name, count(*)
FROM employees
JOIN departments
ON employees.dept_id = departments.dept_id
GROUP BY departments.dept_id, departments.dept_name
Group by dept_name not dept_id
SELECT count(*), dept_name
FROM employees, departments
WHERE employees.dept_id = departments.dept_id
GROUP BY departments.dept_name
And you can better use join like Juan Carlos Oropeza's answer:
SELECT count(*), dept_name
FROM employees JOIN departments ONemployees.dept_id = departments.dept_id
GROUP BY departments.dept_name

display all departments and all employees

if there :
(department) table: (id,name)
(employee) table : (id,dept_id,name)
how to show every department (id,name), then all employees (id,name) in this department under its department.
I'd like it as SQL statment
You need to use JOIN
I believe it's something like this:
SELECT department.id, department.name, employee.id, employee.name
FROM department
LEFT JOIN employee
ON department.id=employee.dept_id
ORDER BY department.id
Since all employees must be present under a particular department at any time, you can do a inner join on both the table with dept_id like
SELECT dept.id, dept.name, emp.id, emp.name
FROM department dept
JOIN employee emp
ON dept.id=emp.dept_id
Simply try this
SELECT D.ID,D.Name,E.ID,E.Name
FROM Department D Left JOIN Employee E ON E.dept_id = D.Id

Joining three tables (link table)

Need help with a query that I wrote:
I have three tables
Company
id name
1 Gary's
Employee
id name company_id
1 Tim Jones 1
2 Sam Adams 1
reports to
employee_id reports_to_id
1 2
My current query is:
select
temp.company.name as comp_name,
temp.employee.name as employee_name,
temp.employee.id as employee_id
from temp.employee, temp.employee
where temp.company.id = temp.employee.company_id and temp.company.id = 1
Which gives me the output of:
comp_name employee_name employee_id
Gary's Tim Jones 1
I need something like this:
comp_name employee_name reports_to
Gary's Tim Jones Sam Adams
What's a good way to modify my query to do this? I have a query and then I take those results and run a second query against that result set (which is excessively unnecessary).
Assuming an employee only reports to one person then we could have (no link table)
Employee (Id, Name, CompanyId, ReportsToId)
Company (Id, Name)
Then you could have a query similar to
select e.Name EmployeeName, c.Name CompanyName, r.Name ReportsTo
from
Employee e
inner join Company c on e.CompanyId = c.Id
inner join Employee r on e.ReportsToId = r.Id
where
e.CompanyId = 1
If the employee reports to multiple people then we would use a link table
Employee (Id, Name, CompanyId)
EmployeeReportsTo (EmployeeId, ManagerId)
Company (Id, Name)
select e.Name EmployeeName, c.Name CompanyName, r.Name ReportsTo
from
Employee e
inner join Company c on e.CompanyId = c.Id
inner join EmployeeReportsTo ert on ert.EmployeeId = e.Id
inner join Employee r on ert.ManagerId = r.Id
where
e.CompanyId = 1