Skip to content

Commit be56e9e

Browse files
authored
Add files via upload
1 parent bfc64ea commit be56e9e

8 files changed

+593
-0
lines changed

Hard/Cumulative Salary.sql

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
-- Question 102
2+
-- The Employee table holds the salary information in a year.
3+
4+
-- Write a SQL to get the cumulative sum of an employee's salary over a period of 3 months but exclude the most recent month.
5+
6+
-- The result should be displayed by 'Id' ascending, and then by 'Month' descending.
7+
8+
-- Example
9+
-- Input
10+
11+
-- | Id | Month | Salary |
12+
-- |----|-------|--------|
13+
-- | 1 | 1 | 20 |
14+
-- | 2 | 1 | 20 |
15+
-- | 1 | 2 | 30 |
16+
-- | 2 | 2 | 30 |
17+
-- | 3 | 2 | 40 |
18+
-- | 1 | 3 | 40 |
19+
-- | 3 | 3 | 60 |
20+
-- | 1 | 4 | 60 |
21+
-- | 3 | 4 | 70 |
22+
-- Output
23+
24+
-- | Id | Month | Salary |
25+
-- |----|-------|--------|
26+
-- | 1 | 3 | 90 |
27+
-- | 1 | 2 | 50 |
28+
-- | 1 | 1 | 20 |
29+
-- | 2 | 1 | 20 |
30+
-- | 3 | 3 | 100 |
31+
-- | 3 | 2 | 40 |
32+
33+
34+
-- Explanation
35+
-- Employee '1' has 3 salary records for the following 3 months except the most recent month '4': salary 40 for month '3', 30 for month '2' and 20 for month '1'
36+
-- So the cumulative sum of salary of this employee over 3 months is 90(40+30+20), 50(30+20) and 20 respectively.
37+
38+
-- | Id | Month | Salary |
39+
-- |----|-------|--------|
40+
-- | 1 | 3 | 90 |
41+
-- | 1 | 2 | 50 |
42+
-- | 1 | 1 | 20 |
43+
-- Employee '2' only has one salary record (month '1') except its most recent month '2'.
44+
-- | Id | Month | Salary |
45+
-- |----|-------|--------|
46+
-- | 2 | 1 | 20 |
47+
48+
49+
-- Employ '3' has two salary records except its most recent pay month '4': month '3' with 60 and month '2' with 40. So the cumulative salary is as following.
50+
-- | Id | Month | Salary |
51+
-- |----|-------|--------|
52+
-- | 3 | 3 | 100 |
53+
-- | 3 | 2 | 40 |
54+
55+
-- Solution
56+
with t1 as(
57+
select *, max(month) over(partition by id) as recent_month
58+
from employee)
59+
60+
select id, month, sum(salary) over(partition by id order by month rows between 2 preceding and current row) as salary
61+
from t1
62+
where month<recent_month
63+
order by 1, 2 desc
64+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
-- Question 14
2+
-- The Employee table holds all employees. Every employee has an Id, and there is also a column for the department Id.
3+
4+
-- +----+-------+--------+--------------+
5+
-- | Id | Name | Salary | DepartmentId |
6+
-- +----+-------+--------+--------------+
7+
-- | 1 | Joe | 85000 | 1 |
8+
-- | 2 | Henry | 80000 | 2 |
9+
-- | 3 | Sam | 60000 | 2 |
10+
-- | 4 | Max | 90000 | 1 |
11+
-- | 5 | Janet | 69000 | 1 |
12+
-- | 6 | Randy | 85000 | 1 |
13+
-- | 7 | Will | 70000 | 1 |
14+
-- +----+-------+--------+--------------+
15+
-- The Department table holds all departments of the company.
16+
17+
-- +----+----------+
18+
-- | Id | Name |
19+
-- +----+----------+
20+
-- | 1 | IT |
21+
-- | 2 | Sales |
22+
-- +----+----------+
23+
-- Write a SQL query to find employees who earn the top three salaries in each of the department. For the above tables, your SQL query should return the following rows (order of rows does not matter).
24+
25+
-- +------------+----------+--------+
26+
-- | Department | Employee | Salary |
27+
-- +------------+----------+--------+
28+
-- | IT | Max | 90000 |
29+
-- | IT | Randy | 85000 |
30+
-- | IT | Joe | 85000 |
31+
-- | IT | Will | 70000 |
32+
-- | Sales | Henry | 80000 |
33+
-- | Sales | Sam | 60000 |
34+
-- +------------+----------+--------+
35+
-- Explanation:
36+
37+
-- In IT department, Max earns the highest salary, both Randy and Joe earn the second highest salary,
38+
-- and Will earns the third highest salary.
39+
-- There are only two employees in the Sales department,
40+
-- Henry earns the highest salary while Sam earns the second highest salary.
41+
42+
-- Solution
43+
select a.department, a.employee, a.salary
44+
from (
45+
select d.name as department, e.name as employee, salary,
46+
dense_rank() over(Partition by d.name order by salary desc) as rk
47+
from Employee e join Department d
48+
on e.departmentid = d.id) a
49+
where a.rk<4

Hard/Human traffic of stadium.sql

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
-- Question 99
2+
-- X city built a new stadium, each day many people visit it and the stats are saved as these columns: id, visit_date, people
3+
4+
-- Please write a query to display the records which have 3 or more consecutive rows and the amount of people more than 100(inclusive).
5+
6+
-- For example, the table stadium:
7+
-- +------+------------+-----------+
8+
-- | id | visit_date | people |
9+
-- +------+------------+-----------+
10+
-- | 1 | 2017-01-01 | 10 |
11+
-- | 2 | 2017-01-02 | 109 |
12+
-- | 3 | 2017-01-03 | 150 |
13+
-- | 4 | 2017-01-04 | 99 |
14+
-- | 5 | 2017-01-05 | 145 |
15+
-- | 6 | 2017-01-06 | 1455 |
16+
-- | 7 | 2017-01-07 | 199 |
17+
-- | 8 | 2017-01-08 | 188 |
18+
-- +------+------------+-----------+
19+
-- For the sample data above, the output is:
20+
21+
-- +------+------------+-----------+
22+
-- | id | visit_date | people |
23+
-- +------+------------+-----------+
24+
-- | 5 | 2017-01-05 | 145 |
25+
-- | 6 | 2017-01-06 | 1455 |
26+
-- | 7 | 2017-01-07 | 199 |
27+
-- | 8 | 2017-01-08 | 188 |
28+
-- +------+------------+-----------+
29+
-- Note:
30+
-- Each day only have one row record, and the dates are increasing with id increasing.
31+
32+
-- Solution
33+
select a.id, a.visit_date, a.people
34+
from
35+
(select id, visit_date, people, id - row_number() over(order by visit_date) as dates
36+
from stadium
37+
where people>=100) a
38+
left join
39+
(select b.dates, count(*) as total
40+
from
41+
(select id, visit_date, people, id - row_number() over(order by visit_date) as dates
42+
from stadium
43+
where people>=100) b
44+
group by dates) c
45+
on a.dates = c.dates
46+
where c.total>2

Hard/Market Analysis 2.sql

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
-- Question 103
2+
-- Table: Users
3+
4+
-- +----------------+---------+
5+
-- | Column Name | Type |
6+
-- +----------------+---------+
7+
-- | user_id | int |
8+
-- | join_date | date |
9+
-- | favorite_brand | varchar |
10+
-- +----------------+---------+
11+
-- user_id is the primary key of this table.
12+
-- This table has the info of the users of an online shopping website where users can sell and buy items.
13+
-- Table: Orders
14+
15+
-- +---------------+---------+
16+
-- | Column Name | Type |
17+
-- +---------------+---------+
18+
-- | order_id | int |
19+
-- | order_date | date |
20+
-- | item_id | int |
21+
-- | buyer_id | int |
22+
-- | seller_id | int |
23+
-- +---------------+---------+
24+
-- order_id is the primary key of this table.
25+
-- item_id is a foreign key to the Items table.
26+
-- buyer_id and seller_id are foreign keys to the Users table.
27+
-- Table: Items
28+
29+
-- +---------------+---------+
30+
-- | Column Name | Type |
31+
-- +---------------+---------+
32+
-- | item_id | int |
33+
-- | item_brand | varchar |
34+
-- +---------------+---------+
35+
-- item_id is the primary key of this table.
36+
37+
38+
-- Write an SQL query to find for each user, whether the brand of the second item (by date) they sold is their favorite brand. If a user sold less than two items, report the answer for that user as no.
39+
40+
-- It is guaranteed that no seller sold more than one item on a day.
41+
42+
-- The query result format is in the following example:
43+
44+
-- Users table:
45+
-- +---------+------------+----------------+
46+
-- | user_id | join_date | favorite_brand |
47+
-- +---------+------------+----------------+
48+
-- | 1 | 2019-01-01 | Lenovo |
49+
-- | 2 | 2019-02-09 | Samsung |
50+
-- | 3 | 2019-01-19 | LG |
51+
-- | 4 | 2019-05-21 | HP |
52+
-- +---------+------------+----------------+
53+
54+
-- Orders table:
55+
-- +----------+------------+---------+----------+-----------+
56+
-- | order_id | order_date | item_id | buyer_id | seller_id |
57+
-- +----------+------------+---------+----------+-----------+
58+
-- | 1 | 2019-08-01 | 4 | 1 | 2 |
59+
-- | 2 | 2019-08-02 | 2 | 1 | 3 |
60+
-- | 3 | 2019-08-03 | 3 | 2 | 3 |
61+
-- | 4 | 2019-08-04 | 1 | 4 | 2 |
62+
-- | 5 | 2019-08-04 | 1 | 3 | 4 |
63+
-- | 6 | 2019-08-05 | 2 | 2 | 4 |
64+
-- +----------+------------+---------+----------+-----------+
65+
66+
-- Items table:
67+
-- +---------+------------+
68+
-- | item_id | item_brand |
69+
-- +---------+------------+
70+
-- | 1 | Samsung |
71+
-- | 2 | Lenovo |
72+
-- | 3 | LG |
73+
-- | 4 | HP |
74+
-- +---------+------------+
75+
76+
-- Result table:
77+
-- +-----------+--------------------+
78+
-- | seller_id | 2nd_item_fav_brand |
79+
-- +-----------+--------------------+
80+
-- | 1 | no |
81+
-- | 2 | yes |
82+
-- | 3 | yes |
83+
-- | 4 | no |
84+
-- +-----------+--------------------+
85+
86+
-- The answer for the user with id 1 is no because they sold nothing.
87+
-- The answer for the users with id 2 and 3 is yes because the brands of their second sold items are their favorite brands.
88+
-- The answer for the user with id 4 is no because the brand of their second sold item is not their favorite brand.
89+
90+
-- Solution
91+
with t1 as(
92+
select user_id,
93+
case when favorite_brand = item_brand then "yes"
94+
else "no"
95+
end as 2nd_item_fav_brand
96+
from users u left join
97+
(select o.item_id, seller_id, item_brand, rank() over(partition by seller_id order by order_date) as rk
98+
from orders o join items i
99+
using (item_id)) a
100+
on u.user_id = a.seller_id
101+
where a.rk = 2)
102+
103+
select u.user_id as seller_id, coalesce(2nd_item_fav_brand,"no") as 2nd_item_fav_brand
104+
from users u left join t1
105+
using(user_id)

Hard/Median Employee Salary.sql

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-- Question 105
2+
-- The Employee table holds all employees. The employee table has three columns: Employee Id, Company Name, and Salary.
3+
4+
-- +-----+------------+--------+
5+
-- |Id | Company | Salary |
6+
-- +-----+------------+--------+
7+
-- |1 | A | 2341 |
8+
-- |2 | A | 341 |
9+
-- |3 | A | 15 |
10+
-- |4 | A | 15314 |
11+
-- |5 | A | 451 |
12+
-- |6 | A | 513 |
13+
-- |7 | B | 15 |
14+
-- |8 | B | 13 |
15+
-- |9 | B | 1154 |
16+
-- |10 | B | 1345 |
17+
-- |11 | B | 1221 |
18+
-- |12 | B | 234 |
19+
-- |13 | C | 2345 |
20+
-- |14 | C | 2645 |
21+
-- |15 | C | 2645 |
22+
-- |16 | C | 2652 |
23+
-- |17 | C | 65 |
24+
-- +-----+------------+--------+
25+
-- Write a SQL query to find the median salary of each company. Bonus points if you can solve it without using any built-in SQL functions.
26+
27+
-- +-----+------------+--------+
28+
-- |Id | Company | Salary |
29+
-- +-----+------------+--------+
30+
-- |5 | A | 451 |
31+
-- |6 | A | 513 |
32+
-- |12 | B | 234 |
33+
-- |9 | B | 1154 |
34+
-- |14 | C | 2645 |
35+
-- +-----+------------+--------+
36+
37+
-- Solution
38+
select id, company, salary
39+
from
40+
(select *,
41+
row_number() over(partition by company order by salary) as rn,
42+
count(*) over(partition by company) as cnt
43+
from employee) a
44+
where rn between cnt/2 and cnt/2+1

0 commit comments

Comments
 (0)