728x90

문제
- machine 별 프로세스 평균 시간 구하기
- 프로세스 완료 시간은 activity_type이 'end'인 timestamp에서 'start'인 timestamp를 빼면 됨.
- 결과는 소수점 셋째자리로 표현하기
테이블
Activity | machine_id | process_id | activity_type | timestamp |
0 | 0 | start | 0.712 | |
0 | 0 | end | 1.520 | |
0 | 1 | start | 3.140 | |
0 | 1 | end | 4.120 | |
1 | 0 | start | 0.550 | |
1 | 0 | end | 1.550 | |
1 | 1 | start | 0.430 | |
1 | 1 | end | 1.420 | |
2 | 0 | start | 4.100 | |
2 | 0 | end | 4.512 | |
2 | 1 | start | 2.500 | |
2 | 1 | end | 5.000 |
- machine_id 별로 processing_time 구하기
- processing_time은 한 기계(machine_id) 당 process_id 별 (end 시간 - start 시간)의 평균
풀이과정
# 튜플 형식으로 셀프조인, activity_type이 다른 경우 조인
- 한 기계 당 여러 프로세스들이 돌아가고 있음. 기계 별로 프로세스들의 평균 러닝타임을 구해야 함.
- 평균 러닝타임 = 기계 별 프로세스 별 ( '마감' 시간 - '시작' 시간)의 평균
- 프로세스 별로 '마감'시간과 '시작' 시간을 한 행으로 보기 위해 셀프 조인을 해줌
- 조인 조건은 ① machine_id와 process_id가 같은 경우에, ② activiy_type이 다른 경우('end', 'start')에만 조인되도록 설정
- 같은 machine_id와 process_id를 가지고 있으면서,
activity_type이 'start'인 경우에는 'end'인 경우의 데이터가 추가되고,
activity_type이 'end'인 경우에는 'start'인 경우의 데이터가 추가됨.
→ (셀프 코드 피드백) 메모리를 비효율적으로 사용하고 있음.
하나의 machine_id와 process_id 별 start 시간과 end 시간을 표현할 때 두 행을 사용하고 있음.
- 같은 machine_id와 process_id를 가지고 있으면서,

# 정답
- SELECT 문으로 machine_id와 activity_type 간 차이의 절댓값의 평균을 계산한 processing_time을 조회해주기
- 상단 풀이과정에서 서술했듯,
같은 machine_id와 process_id 별로 activity_type이 다른 경우에 셀프 조인이 된 상태이기 때문에
두 activity_type 데이터를 빼면 한 행은 +값이 나오고, 다른 행은 -값이 나오게 됨.
- 상단 풀이과정에서 서술했듯,

- activity_type이 다른 경우, 두 값을 빼고 절댓값을 취해줌. 그 후 평균을 구하고, ROUND 함수로 소수점 자리를 맞춰줌.
→ 다행히 평균을 구하는 문제였기 때문에 여기에서 절댓값들을 더한 뒤 1/N 했을 때 정답이 나오게 된 것. - 한 기계 당 프로세스 평균 러닝타임을 구하기 위해서는 machine_id로 GROUP BY 해야 함.
1
2
3
4
5
|
SELECT a1.machine_id, ROUND(AVG(ABS(a1.timestamp-a2.timestamp)),3) processing_time
FROM Activity a1
JOIN Activity a2 ON (a1.machine_id, a1.process_id) = (a2.machine_id, a2.process_id)
AND a1.activity_type != a2.activity_type
GROUP BY a1.machine_id
|
cs |
다른 사람 풀이
# 튜플 형식으로 셀프조인, activity_type을 지정해서 조인
- 프로세스 별로 '마감'시간과 '시작' 시간을 한 행으로 보기 위해 셀프 조인을 해줌
- 조인 조건은 ① machine_id와 process_id가 같은 경우에, ② 왼쪽 테이블은 activity_type이 'start'이고, ③ 오른쪽 테이블은 activity_type이 'end'인 경우에 조인되도록 설정
- 같은 machine_id와 process_id를 가지고 있으면서,
왼쪽 테이블의 activity_type은 'start'이면서 오른쪽 테이블의 activity_type이 'end'일 때 데이터가 추가됨.
→ 한 machine_id와 process_id 별 시작(start)과 마감(end) 시간이 한 행에 나옴.
- 같은 machine_id와 process_id를 가지고 있으면서,
- 두 timestamp 값의 차이를 구한 뒤 평균을 구하고, ROUND 함수로 소수점 자리를 맞춰줌.
- 한 기계 당 프로세스 평균 러닝타임을 구하기 위해서는 machine_id로 GROUP BY 해야 함.
1
2
3
4
5
|
SELECT a1.machine_id, ROUND(AVG(a2.timestamp - a1.timestamp), 3) processing_time
FROM Activity a1
JOIN Activity a2 ON (a1.machine_id, a1.process_id) = (a2.machine_id, a2.process_id)
AND a1.activity_type = 'start' AND a2.activity_type = 'end'
GROUP BY a1.machine_id
|
cs |
728x90
'데이터분석 과정 > SQL' 카테고리의 다른 글
MySQL 리트코드 | Not Boring Movies (%, MOD함수) (0) | 2025.03.28 |
---|---|
MySQL 리트코드 | Confirmation Rate (AVG 함수 내 조건문 사용법) (0) | 2025.03.27 |
MySQL 리트코드 | Rising Temperature (DATEDIFF, TIMESTAMPDIFF, DATE_ADD, DATE_SUB) (0) | 2025.03.18 |
SQL | 데이터 정리(없는 데이터, 사용할 수 없는 데이터) (1) | 2024.01.08 |
SQL | 날짜 데이터 포맷, 조건 (1) | 2024.01.08 |
댓글