Skip to content

Added basic SQL problems #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions LeetcodeProblems/Databases/Classes_More_Than_5_Students.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Classes More Than 5 Students
https://leetcode.com/problems/classes-more-than-5-students/

There is a table courses with columns: student and class

Please list out all classes which have more than or equal to 5 students.

For example, the table:

+---------+------------+
| student | class |
+---------+------------+
| A | Math |
| B | English |
| C | Math |
| D | Biology |
| E | Math |
| F | Computer |
| G | Math |
| H | Math |
| I | Math |
+---------+------------+
Should output:

+---------+
| class |
+---------+
| Math |
+---------+


Note:
The students should not be counted duplicate in each course.
*/

SELECT class
FROM courses
GROUP BY class
HAVING count(DISTINCT(student)) > 4
33 changes: 33 additions & 0 deletions LeetcodeProblems/Databases/Consecutive_Numbers.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Consecutive Numbers
https://leetcode.com/problems/consecutive-numbers/

Write a SQL query to find all numbers that appear at least three times consecutively.

+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
For example, given the above Logs table, 1 is the only number that appears consecutively for at least three times.

+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+
*/

SELECT DISTINCT(l1.Num) AS ConsecutiveNums
FROM
Logs l1, Logs l2, Logs l3
WHERE (
l1.Num = l2.Num AND l1.Id = (l2.Id + 1) AND
l2.Num = l3.Num AND l2.Id = (l3.Id + 1)
)
37 changes: 37 additions & 0 deletions LeetcodeProblems/Databases/Customers_Who_Never_Order.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Customers Who Never Order

SQL Schema
Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL query to find all customers who never order anything.

Table: Customers.

+----+-------+
| Id | Name |
+----+-------+
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
+----+-------+
Table: Orders.

+----+------------+
| Id | CustomerId |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+
Using the above tables as example, return the following:

+-----------+
| Customers |
+-----------+
| Henry |
| Max |
+-----------+
*/

SELECT Customers.Name as Customers
FROM Customers LEFT JOIN Orders ON customers.id = Orders.CustomerId
WHERE Orders.id IS NULL
29 changes: 29 additions & 0 deletions LeetcodeProblems/Databases/Delete_Duplicate_Emails.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Delete Duplicate Emails
https://leetcode.com/problems/delete-duplicate-emails/

Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique emails based on its smallest Id.

+----+------------------+
| Id | Email |
+----+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
| 3 | john@example.com |
+----+------------------+
Id is the primary key column for this table.
For example, after running your query, the above Person table should have the following rows:

+----+------------------+
| Id | Email |
+----+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
+----+------------------+
Note:

Your output is the whole Person table after executing your sql. Use delete statement.
*/

DELETE person FROM Person person, Person person2
WHERE person.email = person2.email AND person.id > person2.id;
43 changes: 43 additions & 0 deletions LeetcodeProblems/Databases/Department_Highest_Salary.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Department Highest Salary
https://leetcode.com/problems/department-highest-salary/

The Employee table holds all employees. Every employee has an Id, a salary, and there is also a column for the department Id.

+----+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
+----+-------+--------+--------------+
The Department table holds all departments of the company.

+----+----------+
| Id | Name |
+----+----------+
| 1 | IT |
| 2 | Sales |
+----+----------+
Write a SQL query to find employees who have the highest salary in each of the departments. For the above tables, your SQL query should return the following rows (order of rows does not matter).

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Jim | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
Explanation:

Max and Jim both have the highest salary in the IT department and Henry has the highest salary in the Sales department.
*/

SELECT DepartmentName AS Department, Employee.Name as Employee, Employee.Salary
FROM Employee JOIN (
SELECT Department.Name AS DepartmentName, Department.Id AS DepartmentId, Max(Salary) as Salary
FROM Employee JOIN Department ON Employee.DepartmentId = Department.Id
GROUP BY Employee.DepartmentId
) AS t ON Employee.Salary = t.Salary AND Employee.DepartmentId = t.DepartmentId
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Employees Earning More Than Their Managers

https://leetcode.com/problems/employees-earning-more-than-their-managers/

The Employee table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id.

+----+-------+--------+-----------+
| Id | Name | Salary | ManagerId |
+----+-------+--------+-----------+
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | NULL |
| 4 | Max | 90000 | NULL |
+----+-------+--------+-----------+
Given the Employee table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager.

+----------+
| Employee |
+----------+
| Joe |
+----------+
*/

SELECT e1.Name as "Employee"
FROM Employee as e1 Join Employee as e2 ON e1.managerId = e2.id
WHERE e1.Salary > e2.Salary
48 changes: 48 additions & 0 deletions LeetcodeProblems/Databases/Exchange_Seats.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Exchange Seats
https://leetcode.com/problems/exchange-seats/

Mary is a teacher in a middle school and she has a table seat storing students' names and their corresponding seat ids.

The column id is continuous increment.

Mary wants to change seats for the adjacent students.
Can you write a SQL query to output the result for Mary?

+---------+---------+
| id | student |
+---------+---------+
| 1 | Abbot |
| 2 | Doris |
| 3 | Emerson |
| 4 | Green |
| 5 | Jeames |
+---------+---------+
For the sample input, the output is:


+---------+---------+
| id | student |
+---------+---------+
| 1 | Doris |
| 2 | Abbot |
| 3 | Green |
| 4 | Emerson |
| 5 | Jeames |
+---------+---------+
Note:
If the number of students is odd, there is no need to change the last one's seat.
*/

WITH paresAImpares AS (
SELECT (id - 1) AS id, student
FROM seat
WHERE MOD(id, 2) = 0
), imparesAPares AS (
SELECT (id + 1) as id, student
FROM seat
WHERE MOD(id, 2) = 1
)

SELECT id, coalesce(paresAImpares.student, imparesAPares.student, seat.student) AS student
FROM seat LEFT JOIN paresAImpares USING(id) LEFT JOIN imparesAPares using(id)
131 changes: 131 additions & 0 deletions LeetcodeProblems/Databases/Reformat_Department_Table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
Reformat Department Table
https://leetcode.com/problems/reformat-department-table

Table: Department

+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| revenue | int |
| month | varchar |
+---------------+---------+
(id, month) is the primary key of this table.
The table has information about the revenue of each department per month.
The month has values in ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].


Write an SQL query to reformat the table such that there is a department id column and a revenue column for each month.

The query result format is in the following example:

Department table:
+------+---------+-------+
| id | revenue | month |
+------+---------+-------+
| 1 | 8000 | Jan |
| 2 | 9000 | Jan |
| 3 | 10000 | Feb |
| 1 | 7000 | Feb |
| 1 | 6000 | Mar |
+------+---------+-------+

Result table:
+------+-------------+-------------+-------------+-----+-------------+
| id | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |
+------+-------------+-------------+-------------+-----+-------------+
| 1 | 8000 | 7000 | 6000 | ... | null |
| 2 | 9000 | null | null | ... | null |
| 3 | null | 10000 | null | ... | null |
+------+-------------+-------------+-------------+-----+-------------+

Note that the result table has 13 columns (1 for the department id + 12 for the months).
*/




-- better solution
SELECT id,
sum(CASE WHEN month = "Jan" then revenue else NULL END) AS "Jan_Revenue",
sum(CASE WHEN month = "Feb" then revenue else NULL END) AS "Feb_Revenue",
sum(CASE WHEN month = "Mar" then revenue else NULL END) AS "Mar_Revenue",
sum(CASE WHEN month = "Apr" then revenue else NULL END) AS "Apr_Revenue",
sum(CASE WHEN month = "May" then revenue else NULL END) AS "May_Revenue",
sum(CASE WHEN month = "Jun" then revenue else NULL END) AS "Jun_Revenue",
sum(CASE WHEN month = "Jul" then revenue else NULL END) AS "Jul_Revenue",
sum(CASE WHEN month = "Aug" then revenue else NULL END) AS "Aug_Revenue",
sum(CASE WHEN month = "Sep" then revenue else NULL END) AS "Sep_Revenue",
sum(CASE WHEN month = "Oct" then revenue else NULL END) AS "Oct_Revenue",
sum(CASE WHEN month = "Nov" then revenue else NULL END) AS "Nov_Revenue",
sum(CASE WHEN month = "Dec" then revenue else NULL END) AS "Dec_Revenue"
FROM Department
GROUP BY id


-- bad solution
with jan AS (
SELECT id, revenue AS Jan_Revenue
FROM Department
WHERE month = "Jan"
), feb AS (
SELECT id, revenue AS Feb_Revenue
FROM Department
WHERE month = "Feb"
), mar AS (
SELECT id, revenue AS Mar_Revenue
FROM Department
WHERE month = "Mar"
), apr AS (
SELECT id, revenue AS Apr_Revenue
FROM Department
WHERE month = "Apr"
), may AS (
SELECT id, revenue AS May_Revenue
FROM Department
WHERE month = "May"
), jun AS (
SELECT id, revenue AS Jun_Revenue
FROM Department
WHERE month = "Jun"
), jul AS (
SELECT id, revenue AS Jul_Revenue
FROM Department
WHERE month = "Jul"
), aug AS (
SELECT id, revenue AS Aug_Revenue
FROM Department
WHERE month = "Aug"
), sep AS (
SELECT id, revenue AS Sep_Revenue
FROM Department
WHERE month = "Sep"
), oct AS (
SELECT id, revenue AS Oct_Revenue
FROM Department
WHERE month = "Oct"
), nov AS (
SELECT id, revenue AS Nov_Revenue
FROM Department
WHERE month = "Nov"
), decemb AS (
SELECT id, revenue AS Dec_Revenue
FROM Department
WHERE month = "Dec"
)

SELECT Distinct(Department.id), jan.Jan_Revenue, feb.Feb_Revenue, mar.Mar_Revenue, apr.Apr_Revenue, may.May_Revenue, jun.Jun_Revenue, jul.Jul_Revenue, aug.Aug_Revenue, sep.Sep_Revenue, oct.Oct_Revenue, nov.Nov_Revenue, decemb.Dec_Revenue
FROM Department LEFT JOIN jan using(id)
LEFT JOIN feb using(id)
LEFT JOIN mar using(id)
LEFT JOIN apr using(id)
LEFT JOIN may using(id)
LEFT JOIN jun using(id)
LEFT JOIN jul using(id)
LEFT JOIN aug using(id)
LEFT JOIN sep using(id)
LEFT JOIN oct using(id)
LEFT JOIN nov using(id)
LEFT JOIN decemb using(id)

Loading