SQL for a many to many relationship using inner joins - sql

I have the following many-to-many relationship between employees and workgroups:
employees table
-----------------
id
empgroups table
---------------
employee_id
workgroup_id
workorders table
----------------
workgroup_id
I'm trying to write SQL that will list all the workorders for an employee based on the workgroups that employee belongs to.
This is my attempt:
SELECT wonum, workgroup_id
FROM workorders
INNER JOIN employees
ON workorders.employee_id = employee_id
INNER JOIN empgroups
ON employees.employee.id = empgroups.employee_id
WHERE employee_id = 2
The error I get is:
ERROR: schema "employees" does not exist
Sorry - the employee has id not employee.id

Isn't this what you're looking for?
SELECT wonum, workgroup_id
FROM workorders
JOIN empgroups
ON empgroups.workgroup_id = workorders.workgroup_id
JOIN employees
ON employees.employee_id = empgroups.employee_id
WHERE employees.employee_id = 2

SELECT w.wonum, w.workgroup_id
FROM workorders w
JOIN empgroups e USING (workgroup_id)
WHERE e.employee_id = 2
The table employees is not needed at all for this query. USING shortens the syntax in this case. As do table aliases.

Try using this query instead:
SELECT * FROM empgroups
INNER JOIN employees
ON empgroups.empId = employees.id
INNER JOIN workorders
ON empgroups.woId = workorders.id
SqlFiddle

Related

Trouble understanding inner join

Im trying to understand inner join correct use but im having trouble when I have to call more than 2 tables, im using oracle HR schema for tests, so for example im trying this query:
select emps.employee_id,
emps.first_name,
dep.department_name,
dep.department_id,
jh.job_id
from employees emps
inner join departments dep
on emps.department_id = dep.department_id
inner join job_history jh
on dep.department_id = jh.department_id;
which shows the following result:
I know its wrong because first its showing duplicate rows, and second if I run this query
select * from job_history where employee_id = 100;
It shows no results which means that employee 100 (steven) shouldnt be appearing in the results of the first query, I expect first query to show me the results of data that is on employees and also on department and also on job_history which have in common the department_id
HR (human resources schema):
Can anyone help me, what im missing, why it shows duplicate rows?
The job_history table has 3 foreign keys:
employee_id
job_id
department_id
Your INNER JOIN only joins on the DEPARTMENT_ID so you are matching an employee to the job history for any jobs that occurred for their department but not necessarily jobs specific to that employee. Instead, you probably want to join on either the employee_id or the combination of employee_id and department_id.
So, if you want the jobs history for that employee for any department:
select emps.employee_id,
emps.first_name,
dep.department_name,
dep.department_id,
jh.job_id
from employees emps
inner join departments dep
on ( emps.department_id = dep.department_id )
inner join job_history jh
on ( emps.employee_id = jh.employee_id );
Or, if you want the job history for that employee within that department:
select emps.employee_id,
emps.first_name,
dep.department_name,
dep.department_id,
jh.job_id
from employees emps
inner join departments dep
on ( emps.department_id = dep.department_id )
inner join job_history jh
on ( emps.employee_id = jh.employee_id
and emps.department_id = jh.department_id );

Sql select clause with three table

I am trying to write a sql query to show student list for each course.
The diagram below show the database relationship.
The SQL query I have written is:
select * from Courses
inner join Enrollments on Enrollments.CourseId = Courses.CourseId
inner join Student on Enrollments.StudentId = StudentId
where Courses.CourseId = 1
The issue is that i am getting returned alot more data than I expected as only one student is registered for the course but i get ten entries. I am not sure if i have done somethings fundamental wrong or is my query the issue.
This is the data
This is the result
I expected only two rows to be returned.
Thanks
Every column in your query must be qualified with the table's name.
You did not qualify the column StudentId in this join:
inner join Student on Enrollments.StudentId = StudentId
If you did you would find the error which is that there is no column StudentId in the table Student and you should use the column Id:
select * from Courses
inner join Enrollments on Enrollments.CourseId = Courses.CourseId
inner join Student on Enrollments.StudentId = Student.Id
where Courses.CourseId = 1
or better with aliases for the tables:
select *
from Courses as c
inner join Enrollments as e on e.CourseId = c.CourseId
inner join Student as s on e.StudentId = s.Id
where c.CourseId = 1
The primary key of table Student is Id, not StudentId.
So the correct query is:
select * from Courses
inner join Enrollments on Enrollments.CourseId = Courses.CourseId
inner join Student on Enrollments.StudentId = Student.Id
where Courses.CourseId = 1

Does this SQL statement look right?

I wondering is what I am doing right.
select distinct
Departments.Department_No, Departments.Department_Name
from
Departments
join
Employees on Departments.Department_No = Employees.Department_No
join
Jobs on Jobs.Job_ID = Employees.Job_ID
where
Departments.Department_No not in (select distinct Department_No
from Employees
where Employees.Job_ID like '%SA_REP%');
You want to display distinct values of Department Number and Department Name
You join Employees table with Department on Department Number
You join Jobs table with Employees on Job ID
You filter the result by excluding those Department Numbers of the entire Employee table that have a Job ID matching the pattern %SA_REP%
In my opinion you don't need
the join with the Jobs table
the join with the Employees table
you could maybe see if one of the other users' suggestions can bring performance improvement
SELECT DISTINCT departments.department_no,
departments.department_name
FROM departments
WHERE departments.department_no NOT IN (SELECT DISTINCT department_no
FROM employees
WHERE employees.job_id LIKE '%SA_REP%'
);
You could simply do this using NOT EXISTS instead of using a NOT IN subquery:
SELECT DISTINCT
d.Department_No
,d.Department_Name
FROM Departments d
JOIN Employees e ON d.Department_No = e.Department_No
WHERE NOT EXISTS
(select 1
from Employees e1
where e1.Job_ID like '%SA_REP%'
AND e1.Department_No = e.Department_No);
You can translate where condition without "in".
And you don't need to fetch date from "Jobs" - you don't use it
Select distinct Departments.Department_No, Departments.Department_Name
from Departments
Join Employees on Departments.Department_No = Employees.Department_No
where Employees.Job_ID not like '%SA_REP%';

How to include rows with missing data in SQL Server 2008

Let's say I have a table a table of employees and another employee_address.
Additionally, I have a table of employee_email_address (employees don't have to have an email)
select
employee.emp_id,
employee_address.address,
employee_email_address.email
from
employees
inner join
employee_address on employee.emp_id = employee_address.emp_id
inner join
employee_email_address on employee_email_address.emp_id = employee.emp_id
but what this query is giving me is only the employees who have an address AND an email address....
How can I include rows for which there is no email_address for the employees? (Note, the email address is not null)
Thanks.
Use left join instead of inner join.
Try this query:
Select e.emp_id, ea.address, eea.email
from employees e left join
employee_address ea
on ea.emp_id = e.emp_id left join
employee_email_address eea
on eea.emp_id = e.emp_id;

SQL inner join and subquery

I am trying to use a sub query on an inner join to get back all department numbers and names from a table that do not have programmer in the department, but I am having a little trouble as it returns no values. Here is my code, thanks for any help.
select Departments.Department_Name, Departments.Department_No
from employees inner join departments
on departments.department_No = employees.Department_No
where Employees.Department_No !=
(select Department_Name
from Employees, Departments
where Job_ID = '%pro%')
From what I can gather, you want something like this:
select d.Department_Name, d.Department_No
from departments d
WHERE NOT EXISTS (SELECT 1 FROM Employees
WHERE d.Department_No = Department_No
AND Job_ID LIKE '%pro%')
This selects all departments, for which there doesn't exist an employee whose job_ib contains 'pro'.
Try this one:
select d1.Department_Name,d1.Department_No
from departments d1
where d1.Department_No in ( select e1.Department_No
from Employees e1
where e1.Department_No=d1.Department_No and
e1.job_id not in ('programmer'));