💡
Thành thạo 3 phương pháp join phổ biến bao gồm
left/right join
, cross join
và phép join
thông thường.Câu 1378. Replace Employee ID With The Unique Identifier
Table: Employees
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
Table: EmployeeUNI
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| unique_id | int |
+---------------+---------+
Write a solution to show the unique ID of each user, If a user does not have a unique ID replace just show null.
Đáp án
Có thể sử dụng left join
-- Write your PostgreSQL query statement below
select eu.unique_id, e.name from Employees e left join EmployeeUNI eu on e.id = eu.id;
hoặc right join
-- Write your PostgreSQL query statement below
select eu.unique_id, e.name from EmployeeUNI eu right join Employees e on e.id = eu.id;
Giải thích
Phép join left
hoặc right
sẽ không loại bỏ những dòng mà bảng phụ (EmployeeUNI
) không có dữ liệu nhưng bảng chính có (Employees
).
Khi đó của unique_id
của những nhân viên không có trong bảng EmployeeUNI
sẽ trả về null
.
Câu 1068. Product Sales Analysis I
Table: Sales
+-------------+-------+
| Column Name | Type |
+-------------+-------+
| sale_id | int |
| product_id | int |
| year | int |
| quantity | int |
| price | int |
+-------------+-------+
Table: Product
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| product_id | int |
| product_name | varchar |
+--------------+---------+
Write a solution to report the product_name, year, and price for each sale_id in the Sales table.
Đáp án
-- Write your PostgreSQL query statement below
select
p.product_name,
s.year,
s.price
from
Sales s
join Product p on s.product_id = p.product_id;
Câu 1581. Customer Who Visited but Did Not Make Any Transactions
Table: Visits
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| visit_id | int |
| customer_id | int |
+-------------+---------+
Table: Transactions
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| transaction_id | int |
| visit_id | int |
| amount | int |
+----------------+---------+
Write a solution to find the IDs of the users who visited without making any transactions and the number of times they made these types of visits.
Đáp án
-- Write your PostgreSQL query statement below
SELECT
v.customer_id,
COUNT(v.visit_id) AS count_no_trans
from
Visits v
LEFT JOIN Transactions t ON v.visit_id = t.visit_id
WHERE
t.amount IS NULL
GROUP BY
v.customer_id;
Giải thích
Điểm mấu chốt là sử dụng left join
để tìm ra tập khách hàng đã ghé nhưng không mua hàng.
Câu 197. Rising Temperature
Table: Weather
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| recordDate | date |
| temperature | int |
+---------------+---------+
Write a solution to find all dates' id with higher temperatures compared to its previous dates (yesterday).
Đáp án
select
w2.id
from
Weather w1
join Weather w2 on w2.recordDate = w1.recordDate + '1day' :: interval
and w2.temperature > w1.temperature
Câu 1661. Average Time of Process per Machine
Table: Activity
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| machine_id | int |
| process_id | int |
| activity_type | enum |
| timestamp | float |
+----------------+---------+
There is a factory website that has several machines each running the same number of processes. Write a solution to find the average time each machine takes to complete a process.
Đáp án
select
a1.machine_id,
round(avg(a2.timestamp - a1.timestamp) :: numeric, 3) as processing_time
from
Activity a1
join Activity a2 on a1.machine_id = a2.machine_id
and a1.process_id = a2.process_id
and a1.activity_type = 'start'
and a2.activity_type = 'end'
group by
1
Câu 577. Employee Bonus
Table: Employee
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| empId | int |
| name | varchar |
| supervisor | int |
| salary | int |
+-------------+---------+
Table: Bonus
+-------------+------+
| Column Name | Type |
+-------------+------+
| empId | int |
| bonus | int |
+-------------+------+
Write a solution to report the name and bonus amount of each employee with a bonus less than 1000.
Đáp án
select
e.name,
b.bonus
from
Employee e
left join Bonus b on e.empId = b.empId
where
bonus < 1000
or bonus is null;
Câu 1280. Students and Examinations
Table: Students
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| student_id | int |
| student_name | varchar |
+---------------+---------+
Table: Subjects
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| subject_name | varchar |
+--------------+---------+
Table: Examinations
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| student_id | int |
| subject_name | varchar |
+--------------+---------+
Write a solution to find the number of times each student attended each exam.
Đáp án
-- Write your PostgreSQL query statement below
select
cj.student_id,
cj.student_name,
cj.subject_name,
coalesce(count(e.subject_name)) attended_exams
from
(
select
*
from
Students
cross join Subjects
) cj
left join Examinations e on cj.student_id = e.student_id
and cj.subject_name = e.subject_name
group by
1,
2,
3
Câu 570. Managers with at Least 5 Direct Reports
Table: Employee
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
| department | varchar |
| managerId | int |
+-------------+---------+
Write a solution to find managers with at least five direct reports.
Đáp án
select
name
from
Employee e
join (
select
managerId,
count(distinct id) as c
from
Employee
where
managerId is not null
and id != managerId
group by
1
) agg on agg.managerId = e.id
and agg.c >= 5
Câu 1934. Confirmation Rate
Table: Signups
+----------------+----------+
| Column Name | Type |
+----------------+----------+
| user_id | int |
| time_stamp | datetime |
+----------------+----------+
Table: Confirmations
+----------------+----------+
| Column Name | Type |
+----------------+----------+
| user_id | int |
| time_stamp | datetime |
| action | ENUM |
+----------------+----------+
Write a solution to find the confirmation rate of each user.
Đáp án
select
s.user_id,
coalesce(round(r, 2), 0.00) as confirmation_rate
from
Signups s
left join (
select
user_id,
(
count(time_stamp) filter (
where
action = 'confirmed'
)
) / count(time_stamp)::numeric as r
from
Confirmations
group by
1
) rts on s.user_id = rts.user_id