SQL inner join and subquery - sql

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'));

Related

Subquery using 3 Tables SQL

I'm trying to display the last name of the lowest paid employees from each city. The city column falls under a table titled LOCATIONS while employee information(salary, last name) falls under EMPLOYEES. Both of these tables are related share no common table, so I have to rely on a third table, DEPARTMENTS to connect the two as DEPARTMENTS contains a department_id that it shares with EMPLOYEES as well as a LOCATION_ID that it shares with LOCATIONS. This is what I have so far, but I'm having trouble with this as I've mostly worked with only two tables in the past.
SELECT LAST_NAME
FROM EMPLOYEES
WHERE (DEPARTMENT_ID) IN
(SELECT DEPARTMENT_ID
FROM DEPARTMENTS
WHERE LOCATION_ID IN
(SELECT LOCATION_ID
FROM LOCATIONS
GROUP BY CITY
HAVING MIN(SALARY)));
This seems to be an assignment in an intro course in SQL. So let's assume you can't use analytic functions, match_recognize clause, etc. Just joins and aggregates.
In the subquery in the WHERE clause below, we compute the min salary for each city. We need to join all three tables for this. Then in the overall query we join the three tables again, and we use the subquery for an IN condition (a semi-join). The overall query looks like this:
select e.last_name
from employees e join departments d
on e.department_id = d.department_id
join locations l
on d.location_id = l.location_id
where ( e.salary, l.city ) in
(
select min(salary), city
from employees e join departments d
on e.department_id = d.department_id
join locations l
on d.location_id = l.location_id
group by city
)
;
You should separate out the concept of table joins from WHERE clauses.
Use WHERE for filtering data, use JOIN for connecting data together.
I think this is what you are wanting. By the way, lose the ALL CAPS if you can.
SELECT
LAST_NAME
FROM
EMPLOYEES
INNER JOIN (
SELECT
DEPARTMENTS.DEPARTMENT_ID,
CITY,
MIN(SALARY) AS LOWEST_SALARY
FROM
EMPLOYEES
INNER JOIN DEPARTMENTS ON EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID
INNER JOIN LOCATIONS ON DEPARTMENTS.LOCATION_ID = LOCATIONS.LOCATION_ID
GROUP BY
DEPARTMENTS.DEPARTMENT_ID,
LOCATIONS.CITY
) AS MINIMUM_SALARIES
ON EMPLOYEES.DEPARTMENT_ID = MINIMUM_SALARIES.DEPARTMENT_ID
AND EMPLOYEES.SALARY = MINIMUM_SALARIES.LOWEST_SALARY
First of all join the tables, so you see city and employee in one row. If we group by city we get the minimum salary per city.
with city_employees as
(
select l.city, e.*
from locations l
join departments d using (location_id)
join employees e using (department_id)
)
select last_name
from city_employees
where (city, salary) in
(
select city, min(salary)
from city_employees
group by l.city
);
It is easier to achieve the same, however, with window functions (min over or rank over here).
select last_name
from
(
select
e.last_name,
e.salary,
min(e.salary) over (partition by l.city) as min_salary
from locations l
join departments d using (location_id)
join employees e using (department_id)
)
where salary = min_salary;

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 get all departments with Employee number

I have an EmployeeDepartmetn juction table like this. I have all the departments in Depeartment table and employees in Employee table..
I want to get departments for an particular employee along with the all the departments available in depeartment table.
It should be like Select DepartmentId, DepartmentName, EmployeeID from Query.
Main criteria here is, Need to display NULL if the employee dont have that department. I am confused here...please help.
Please give Linq Query
Thanks in Advance
Put criteria in your left join:
Select distinct a.DeptID, b.DepartmentName, b.EmployeeID
From Department a
left join EmployeeDepartment b
on a.DeptID = b.DeptID and b.EmployeeID = 1 --insert employee ID here
It will show all departments (even those with no employees), then show the employee ID you chose in the third column only if that employee is assigned there.
You can do this with conditional aggregation:
select DeptId,
max(case when EmployeeId = 1 then EmployeeId end) as EmployeeId
from EmployeeDepartment ed
group by DeptId;
EDIT:
If you have a departments table as well:
select d.deptid, d.name, ed.employeeid
from Departments d left join
EmployeeDepartment ed
on d.deptid = ed.deptid and
ed.employeeid = 1;

Include rows that contain null values in a particular column with inner join

The goal here is to return the ID, Name, and Manager Name and ID for each Employee. The table does not contain a manager name, only a manager ID for a given employee. The current query works great using an inner join, except that one employee does not have a manager ID (he's the boss), and so none of his information appears. The current query looks like this:
SELECT DISTINCT e.employee_id AS EMPLOYEE_ID,
e.FULL_NAME AS EMPLOYEE_NAME,
m.manager_ID AS REPORTS_TO,
m.FULL_NAME AS MANAGER_NAME
FROM EMPS e
INNER JOIN EMPS m ON e.manager_id = m.employee_id;
How can I include the name and information for this employee despite his lack of a seemingly necessary field? Thanks
If you want to include the employee name when there is no manager do a left join:
SELECT DISTINCT e.employee_id AS EMPLOYEE_ID,
e.FULL_NAME AS EMPLOYEE_NAME,
m.manager_ID AS REPORTS_TO,
m.FULL_NAME AS MANAGER_NAME
FROM EMPS e
LEFT JOIN EMPS m ON e.manager_id = m.employee_id;

How to add subquery as a column in SQL

How do I add a subquery as a column in my SQL script?
e.g.
Select emp_no, name,gender ,
(select department_name from departments where employees.emp_no = departments.emp_no)
from employees
PS: I'm using oracle 8
Going by the semantics, what I understand is that you want an employee's department name to be shown alongside his/her other information. I would suggest you do a join instead:
Select emp_no, name, gender, department_name
from employees emp, departments dept
where emp.emp_no = dept.emp_no;
That looks reasonably sound, I would suggest some (possible typos) cleaning up: add a comma after "gender" and declare the table names, also set the subquery alias
Select employees.emp_no, employees.name, employees.gender,
(select departments.department_name from departments where employees.emp_no = departments.emp_no) as dept_name
from employees
Alternatively, a nice join would would work too, if the other data is feasible:
Select employees.emp_no, employees.name, employees.gender, departments.department_name
from employees
inner join departments on employees.emp_no = departments.emp_no
left join is the best-practice, and should be faster in performance:
Select e.emp_no, e.name, e.gender , d.department_name
from employees e left join departments d on e.emp_no = d.emp_no;
You seem to be missing comma after gender.
Select emp_no, name,gender ,
(select department_name from departments where employees.emp_no = departments.emp_no) as dept_name from employees
The below is what you need. Just added a comma after gender. This subquery would need to return only one row for each result as well or else an error will be seen.
Select emp_no, name,gender,
(select department_name from departments where employees.emp_no = departments.emp_no)
from employees
This query is your answer but it will work only if there is one column mentioned in that if we use more than one column than it will retrun an error .
"Select employee_id,first_name,
(select department_name,manager_id from departments where employees.department_id = departments.department_id) as new_column
from employees;"
can you try this:
SELECT em.emp_no, em."name",em.gender ,
(SELECTdistinctdp.department_name
FROM departments dp
WHERE em.emp_no = dp.emp_no) my_sub
FROM employees em