Alternative SQLs in Chapter 3B
P8. Query 1: Find the names of all employees and remove duplicates.
SELECT DISTINCT name
FROM Employees;
Question Try this
What if we do not use the SELECT name
keyword DISTINCT? FROM Employees;
Will applying DISTINCT SELECT DISTINCT employee_id, name
keyword on both FROM Employees;
employee_id, name remove
the resulting rows with
duplicate name?
P10. Query 2: Find the employee_ids and names of employees who work in department with
department_id=2.
SELECT E.employee_id, E.name
FROM Works_in W , Employees E
WHERE W.department_id = 2 AND
E.employee_id = W.employee_id;
Question Try this
Can we use W.employee_id? SELECT W.employee_id, E.name
FROM Works_in W , Employees E
WHERE W.department_id = 2 AND
E.employee_id = W.employee_id;
Can we use JOIN or INNER SELECT E.employee_id, E.name
JOIN instead? FROM Works_in W INNER JOIN Employees E
ON E.employee_id = W.employee_id
WHERE W.department_id = 2
Can we use IN instead of SELECT employee_id, name
joining? FROM Employees
WHERE employee_id IN (
SELECT employee_id
FROM Works_in
WHERE department_id = 2
)
1
P12. Query 3: Find the dept. names where employee with employee_id = 2 works.
SELECT D.name
FROM Works_in W, Departments D
WHERE W.employee_id = 2 AND
D.department_id = W.department_id;
Question Try this
Can we use IN instead of SELECT name
joining? FROM Departments
WHERE department_id IN (
SELECT department_id
FROM Works_in
WHERE employee_id = 2
)
P14. Query 4: Find the dept. ids where employees named Smith work.
SELECT W.department_id
FROM Employees E, Works_in W
WHERE E.name = 'Smith' AND
E.employee_id = W.employee_id;
Question Try this
Can we use IN instead of SELECT department_id
joining? FROM Works_in W
WHERE employee_id IN (
SELECT employee_id
FROM Employees
WHERE name = 'Smith'
)
Question Try this
What about I want to display SELECT E.employee_id, E.name, W.department_id
the employee_id and his/her FROM Employees E, Works_in W
name together with the WHERE E.name = 'Smith' AND
department ID that employee
E.employee_id = W.employee_id;
works in?
2
P19. Query 6: Find the names of departments which have an employee named Smith and their
budget is greater than 100000.
SELECT D.name
FROM Departments D, Employees E, Works_in W
WHERE D.budget > 100000 AND
E.name = 'Smith' AND
W.employee_id = E.employee_id AND
D.department_id = W.department_id;
Question Try this
Can we use IN instead of Find the departments (department_id) which have an employee
joining? named Smith
SELECT W.department_id
FROM Works_in W, Employees E
WHERE E.name = 'Smith' AND
E.employee_id = W.employee_id
Given those department_id, find the department name in this set
with budget > 10000.
SELECT name
FROM Departments
WHERE budget > 100000 AND
department_id IN (
SELECT W.department_id
FROM Works_in W, Employees E
WHERE E.name = 'Smith' AND
E.employee_id = W.employee_id
);
SELECT name
FROM Departments
WHERE budget > 100000 AND
department_id IN (
SELECT department_id
FROM Works_in
WHERE employee_id IN (
SELECT employee_id
FROM Employees
WHERE name = 'Smith'
)
);
Using INNER JOIN SELECT D.name
FROM Departments D
INNER JOIN Works_in W ON D.department_id = W.department_id
INNER JOIN Employees E ON W.employee_id = E.employee_id
WHERE D.budget > 100000 AND E.name = 'Smith';
3
p.23. Query 7: Find the budgets of departments, who employ an employee called ‘Smith’ .
SELECT D.budget
FROM Employees E, Works_in W, Departments D
WHERE E.name = 'Smith' AND
E.employee_id = W.employee_id AND
W.department_id = D.department_id;
Question Try this
Can we use IN instead of Find the departments (department_id) which have an
joining? employee named Smith
SELECT W.department_id
FROM Works_in W, Employees E
WHERE E.name = 'Smith' AND
E.employee_id = W.employee_id
Given those department_id, find the budget of the
departments
SELECT budget
FROM Departments
WHERE department_id IN (
SELECT W.department_id
FROM Works_in W, Employees E
WHERE E.name = 'Smith' AND
E.employee_id = W.employee_id
);
What about if I also want SELECT E.name, D.name, D.budget
to display the employee FROM Employees E, Works_in W, Departments D
name, and department WHERE E.name = 'Smith' AND
name?
E.employee_id = W.employee_id AND
W.department_id = D.department_id;
Using INNER JOIN version SELECT E.name, D.name, D.budget
FROM Employees E
INNER JOIN Works_in W ON E.employee_id = W.employee_id
INNER JOIN Departments D ON W.department_id =
D.department_id
WHERE E.name = 'Smith';
4
p.24 Query 8: For each department, find the total number of employees it employs.
SELECT W.department_id, COUNT(*)
FROM Works_in W
GROUP BY W.department_id;
Question Try this
Let’s try to add a new INSERT INTO `Departments` (`department_id`, `name`,
department without any `budget`) VALUES ('4', 'Account', '60000');
employee works in, then
the above query won’t Using Left outer join:
display the COUNT of the
employee of the new SELECT *
department. FROM Departments D LEFT OUTER JOIN Works_in W
ON D.department_id = W.department_id
Using GROUP BY
SELECT D.department_id, COUNT(*), COUNT(D.department_id),
COUNT(W.department_id), COUNT(W.employee_id)
FROM Departments D LEFT OUTER JOIN Works_in W
ON D.department_id = W.department_id
GROUP BY D.department_id;
* Do you know why only COUNT(W.employee_id) and
COUNT(W.department_id) returns the correct count?
Better to be the following in order not to miss the entries of Departments with no employee.
5
p.27 Query 9: Find the dept. names with at least 2 employee.
SELECT COUNT(*), D.name
FROM Works_in W, Departments D
WHERE D.department_id = W.department_id
GROUP BY D.department_id
HAVING COUNT(*) >= 2;
Question Try this
What about if we would SELECT COUNT(*), D.name
like to select the FROM Works_in W, Departments D
department names with WHERE D.department_id = W.department_id
less than 2 employee?
GROUP BY D.department_id
HAVING COUNT(*) < 2;
The above query has one department missing!
Using Left outer join:
SELECT COUNT(W.employee_id) AS numOfemployee, D.name
FROM Departments D LEFT OUTER JOIN Works_in W
ON D.department_id = W.department_id
GROUP BY D.department_id
HAVING numOfemployee < 2;
p.28 Query 10: Find the employee_id of all employees whose name includes the substring
“one”.
Question Try this
Can we use regular SELECT employee_id
expression? FROM Employees
WHERE name REGEXP '.*one.*';
* https://dev.mysql.com/doc/refman/8.0/en/regexp.html
6
p.31. Query 11: Find the employee_id and name of the employees who worked in the
departments with budget more than 100,000.
SELECT DISTINCT E.employee_id, E.name
FROM Works_in W, Employees E
WHERE E.employee_id = W.employee_id AND
W.department_id IN (
SELECT department_id
FROM Departments
WHERE budget > 100000);
Question Try this
Can we use joining instead SELECT DISTINCT E.employee_id, E.name
of IN? FROM Works_in W, Employees E, Departments D
WHERE E.employee_id = W.employee_id AND
W.department_id = D.department_id AND
D.budget > 100000;
p.33. Query 12: Find the name and budget of the department with the greatest budget.
SELECT D2.name, D2.budget
FROM Departments D2
WHERE D2.budget = (
SELECT MAX(D.budget)
FROM Departments D
);
Question Try this
Can we use IN instead of =? SELECT D2.name, D2.budget
FROM Departments D2
WHERE D2.budget IN (
SELECT MAX(D.budget)
FROM Departments D
)
Use ORDER BY and LIMIT SELECT name, budget
to return top one FROM Departments
department according to ORDER BY budget DESC
budget order (descending) LIMIT 1
7
p.35 Query 13: Find the names of employees who work in at least 2 departments.
SELECT E.name
FROM Employees E
WHERE 2 <= (
SELECT COUNT(W.department_id)
FROM Works_in W
WHERE W.employee_id = E.employee_id
);
Question Try this
Can we use Grouping and SELECT E.employee_id, E.name, COUNT(*)
aggregation? FROM Works_in W, Employees E
WHERE W.employee_id = E.employee_id
GROUP BY W.employee_id
HAVING COUNT(*) >=2;
What about if we would Try to use the above technique seems okay:
like to find the employees
who works in less than 2 SELECT E.employee_id, E.name, COUNT(*)
departments? FROM Works_in W, Employees E
WHERE W.employee_id = E.employee_id
GROUP BY W.employee_id
HAVING COUNT(*) < 2;
Try adding one new employee and does not work in any
department:
INSERT INTO `Employees` (`employee_id`, `name`, `salary`)
VALUES ('5', 'Kitty', '20000');
Then the above query will miss Kitty. Can we have it back?
SELECT E.employee_id, E.name, COUNT(W.department_id)
FROM Works_in W RIGHT OUTER JOIN Employees E
ON W.employee_id = E.employee_id
GROUP BY E.employee_id
HAVING COUNT(W.department_id) < 2;
8
p.36 Query 14: In each department, find the highest salary of the employee in that
department.
SELECT MAX(E.salary) , W.department_id
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id
GROUP BY W.department_id;
Question Try this
Can we also return the What we want is to have a department table with max salary.
name(s) of the employee(s)
with the highest salary in SELECT MAX(E.salary) maxSal, W.department_id
each department? FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id
GROUP BY W.department_id
Then, we can treat the above as a temporarily table inside a
query:
SELECT E.name, E.salary, A.department_id
FROM
(SELECT MAX(E.salary) maxSal, W.department_id
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id
GROUP BY W.department_id) A,
Works_in W, Employees E
WHERE A.department_id = W.department_id AND
W.employee_id = E.employee_id AND
E.salary = A.maxSal
9
p.40 Query: Find the name of employees who work in department 1 and department 2.
SELECT E.name
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND
W.department_id = 1
INTERSECT
SELECT E.name
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND
W. department_id = 2
Question Try this
Can we use self- SELECT E.name
join (cartesian FROM Employees E, Works_in W1, Works_in W2
product) to WHERE E.employee_id = W1.employee_id AND
replace W1.employee_id = W2.employee_id AND
intersect? W1.department_id = 1 AND
W2.department_id = 2
Can we use First, let us group in the Works_in table according to employee_id, and
GROUP BY and limit on the records for department 1 or department 2.
HAVING instead?
SELECT W.employee_id
FROM Works_in W
WHERE W.department_id =1 OR W.department_id =2
GROUP BY W.employee_id
HAVING COUNT( * ) =2
Then, we can either use IN to retrieve the name
SELECT name
FROM Employees
WHERE employee_id IN (
SELECT W.employee_id
FROM Works_in W
WHERE W.department_id =1 OR W.department_id =2
GROUP BY W.employee_id
HAVING COUNT( * ) =2
)
10
Or we can just use cartesian product to retrieve the name
SELECT E.name
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND
( W.department_id =1 OR W.department_id =2 )
GROUP BY W.employee_id
HAVING COUNT( * ) =2
Can we use SELECT DISTINCT E.name
EXIST? FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND EXISTS (
SELECT *
FROM Works_in W
WHERE W.employee_id = E.employee_id AND W.department_id = 1
) AND EXISTS (
SELECT *
FROM Works_in W
WHERE W.employee_id = E.employee_id AND W.department_id = 2
)
11
p.41 Query: Find the name of employees who work in department 1 but not department 3.
SELECT E.name
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND
W.department_id = 1
EXCEPT
SELECT E.name
FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND
W. department_id = 3
Question Try this
Can we replace EXCEPT by SELECT E.name
NOT IN? FROM Employees E, Works_in W
WHERE E.employee_id = W.employee_id AND
W.department_id = 1 AND
E.employee_id NOT IN (
SELECT W2.employee_id
FROM Works_in W2
WHERE W2. department_id = 3
);
12
p.47 SOME
SELECT D.name
FROM Departments D
WHERE D.budget > SOME(
SELECT D2.budget
FROM Departments D2
WHERE D2.department_id IN (
SELECT W.department_id
FROM Works_in W
WHERE W.employee_id = 4
)
);
Question Try this
Can we use joining for the SELECT D.name
inner part? FROM Departments D
WHERE D.budget > SOME(
SELECT D2.budget
FROM Departments D2, Works_in W
WHERE D2.department_id = W.department_id AND
W.employee_id = 4
);
13
p.50 ALL We can also replace IN by joining
SELECT D.name
FROM Departments D
WHERE D.budget > ALL (
SELECT D2.budget
FROM Departments D2
WHERE D2.department_id IN (
SELECT W.department_id
FROM Works_in W
WHERE W.employee_id = 4
)
);
Question Try this
Can we use joining for the SELECT D.name
inner part? FROM Departments D
WHERE D.budget > ALL (
SELECT D2.budget
FROM Departments D2, Works_in W
WHERE D2.department_id = W.department_id AND
W.employee_id = 4
);
14
p.51.
SELECT D.name
FROM Departments D
WHERE D.budget >= ALL (
SELECT D2.budget
FROM Departments D2
);
Question Try this
>=ALL means equal to SELECT D.name
maximum, can we use FROM Departments D
MAX() to get the max WHERE D.budget =
budget from department, (
and use outer query to find SELECT MAX(W2.budget)
the name of the FROM Departments W2
department(s)? );
Or the following SQL also works:
SELECT D.name
FROM Departments D
WHERE D.budget IN
(
SELECT MAX(W2.budget)
FROM Departments W2
);
15
p.52 Query: Find the names of employees who work in department with department_id=1.
SELECT E.name
FROM Employees E
WHERE EXISTS (
SELECT *
FROM Works_in W
WHERE W.department_id = 1 AND
E.employee_id = W.employee_id);
Question Try this
Can we just use simple SELECT E.name
joining to answer this FROM Employees E, Works_in W
query? WHERE E.employee_id = W.employee_id AND
W.department_id = 1;
p.55 examples for NULL and IS UNKNOWN
Question Try this
What is the result if we SELECT employee_id + NULL FROM Employees;
apply arithmetic operation
with NULL?
What is the result if we SELECT * FROM Employees WHERE employee_id > NULL;
apply comparision
operation with NULL? The above query returns nothing because employee_id > NULL
evaluates to UNKNOWN.
If a row is evaluated to UNKNOWN, it is treated as FALSE and
thus not output.
Try this:
SELECT * FROM Employees WHERE employee_id > NULL IS
UNKNOWN;
16