Skip to content

Instantly share code, notes, and snippets.

@Pluies
Created May 28, 2013 14:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pluies/5663135 to your computer and use it in GitHub Desktop.
Save Pluies/5663135 to your computer and use it in GitHub Desktop.
-- Example Data
DROP TABLE Employees;
DROP TABLE Departments;
CREATE TABLE Departments(DepartmentID INTEGER PRIMARY KEY, Name VARCHAR);
CREATE TABLE Employees(EmployeeID INTEGER PRIMARY KEY, DepartmentID INTEGER, BossID INTEGER, Name VARCHAR, Salary INTEGER);
ALTER TABLE Employees ADD FOREIGN KEY (BossID) REFERENCES Employees(EmployeeID);
ALTER TABLE Employees ADD FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID);
INSERT INTO Departments(DepartmentID, Name)
VALUES(1, 'Exec'),
(2, 'Legal'),
(3, 'IT'),
(4, 'Admin'),
(5, 'Nobody');
INSERT INTO Employees(EmployeeID, DepartmentID, BossID, Name, Salary)
VALUES( 1, 1, 1, 'Chief', 100),
( 2, 3, 1, 'CTO', 95),
( 3, 2, 1, 'CFO', 100),
( 4, 3, 2, 'IT 1', 90),
( 5, 3, 2, 'IT 2', 90),
( 6, 4, 1, 'Adm 1', 20),
( 7, 4, 1, 'Adm 2', 110),
( 8, 3, 2, 'IT 3', 50),
( 9, 3, 1, 'IT 4', 60),
( 10, 2, 3, 'Legal 1', 110),
( 11, 3, 3, 'IT 5', 80),
( 12, 3, 1, 'IT 6', 200);
-- Answers
-- List employees (names) who have a bigger salary than their boss
SELECT a.Name FROM Employees a JOIN Employees b
ON a.BossID = b.EmployeeId
WHERE a.Salary > b.Salary;
-- List employees who have the biggest salary in their departments
SELECT a.Name, a.DepartmentID
FROM Employees a JOIN
(SELECT a.DepartmentID, MAX(Salary)
FROM Employees a JOIN Departments b ON a.DepartmentID = b.DepartmentID
GROUP BY a.DepartmentID) b
ON a.Salary = b.max AND a.DepartmentID = b.DepartmentID;
-- List departments that have less than 3 people in it
SELECT DepartmentID, COUNT(Name)
FROM Employees
GROUP BY DepartmentID
HAVING COUNT(Name) < 3;
-- List all departments along with the number of people there (tricky - people often do an "inner join" leaving out empty departments)
SELECT b.Name, COUNT(a.DepartmentID)
FROM Employees a FULL OUTER JOIN Departments b ON a.DepartmentID=b.DepartmentID
GROUP BY b.Name;
-- List employees that don't have a boss in the same department
SELECT a.Name FROM Employees a JOIN Employees b
ON a.BossID = b.EmployeeId
WHERE a.DepartmentID != b.DepartmentID;
-- List all departments along with the total salary there
SELECT b.Name, SUM(a.Salary)
FROM Employees a FULL OUTER JOIN Departments b ON a.DepartmentID = b.DepartmentID
GROUP BY b.name;
@Pluies
Copy link
Author

Pluies commented May 28, 2013

@twistedpair — indeed, my answer is pretty ugly and complicated for what should be easier... Your solution looks good, but it doesn't run on my Postgres 9.2.4:

florent=# SELECT em.EmployeeID, em.departmentId, MAX(salary) as salary
FROM employees em
GROUP BY em.departmentId;
ERROR: column "em.employeeid" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT em.EmployeeID, em.departmentId, MAX(salary) as salary
^
florent=#

@twistedpair
Copy link

Alas, I was incorrect. MAX(tuple) does not always correlate with the max value's employeeId on MySQL.

Upon further reflection, your solution is indeed the correct one. Nice work. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment