Tables
erDiagram
employees {
employee_id int PK
employee_name varchar
department varchar
}
meetings {
meeting_id int PK
employee_id int FK
meeting_date date
meeting_type varchar "Team, Client, Training"
duration_hours decimal
}
employees || -- o{ meetings : "make meetings"
Mermaid
복사
Question
Write a solution to find employees who are meeting-heavy - employees who spend more than 50% of their working time in meetings during any given week.
•
Assume a standard work week is 40 hours
•
Calculate total meeting hours per employee per week (Monday to Sunday)
•
An employee is meeting-heavy if their weekly meeting hours > 20 hours (50% of 40 hours)
•
Count how many weeks each employee was meeting-heavy
•
Only include employees who were meeting-heavy for at least 2 weeks
Return the result table ordered by the number of meeting-heavy weeks in descending order, then by employee name in ascending order.
DataFlow
per week 구분
주단위 20시간 이상 구분 -> count -> 2주이상 해당되는 직원
Answer
WITH week_mt AS (
SELECT
*,
DATE_FORMAT(meeting_date, "%u") AS weeks
FROM meetings
),
week_mt_time AS (
SELECT
employee_id,
weeks,
SUM(duration_hours) AS mt_time
FROM week_mt
GROUP BY employee_id, weeks
HAVING mt_time > 20
),
week_cnt AS (
SELECT
employee_id,
COUNT(weeks) AS wk_cnt
FROM week_mt_time
GROUP BY employee_id
HAVING wk_cnt >= 2
)
SELECT
w.employee_id,
e.employee_name,
e.department,
w.wk_cnt AS meeting_heavy_weeks
FROM week_cnt w
INNER JOIN employees e
ON w.employee_id = e.employee_id
ORDER BY meeting_heavy_weeks DESC, e.employee_name ASC;
SQL
복사
![[Pasted image 20251024084107.png]]
문제를 풀때는 가독성을 위해서 주로 CTE를 사용해서 푸는데
재사용을 하지 않는다면, 쿼리 효율성은 subquery가 좋고
이번 문제를 풀면서는 주단위 구분을 몰라서 구글링했다.
subquery -> having, where
SELECT
w.employee_id,
e.employee_name,
e.department,
w.wk_cnt AS meeting_heavy_weeks
FROM (
SELECT
employee_id,
COUNT(weeks) AS wk_cnt
FROM (
SELECT
employee_id,
weeks,
SUM(duration_hours) AS mt_time
FROM (
SELECT
*,
DATE_FORMAT(meeting_date, "%u") AS weeks
FROM meetings
) week_mt
GROUP BY employee_id, weeks
) week_mt_time
WHERE mt_time > 20
GROUP BY employee_id
) w
INNER JOIN employees e
ON w.employee_id = e.employee_id AND w.wk_cnt >= 2
ORDER BY meeting_heavy_weeks DESC, e.employee_name ASC;
SQL
복사
WITH process_1 AS (
SELECT
employee_id,
SUM(duration_hours) duration_total
FROM meetings
GROUP BY employee_id, WEEKOFYEAR(meeting_date), YEAR(meeting_date)
)
SELECT
p.employee_id,
e.employee_name,
e.department,
COUNT(p.employee_id) meeting_heavy_weeks
FROM process_1 p
INNER JOIN employees e
ON p.employee_id = e.employee_id
WHERE duration_total > 20
GROUP BY p.employee_id, e.employee_name, e.department
HAVING COUNT(p.employee_id) > 1
ORDER BY meeting_heavy_weeks DESC, employee_name;
SQL
복사
WEEKOFYEAR, YEAR 1년 중 주 단위 추출 함수, 연도가 바뀔 수도 있으니 YEAR와 함께 group by