Hayden's Archive

[MySQL] 서브쿼리(Sub Query) 활용 문제 본문

Study/DB

[MySQL] 서브쿼리(Sub Query) 활용 문제

_hayden 2020. 5. 10. 14:06

처음에 5번 문제를 잘못 해석했다.

내가 처음에 해석한 것 : '평균 급여보다 많은 급여를 받고 이름에 u가 포함된 사원'과 같은 부서에서 근무하는 모든 사원의 사원 번호, 이름 및 급여를 표시하시오.

-- 내가 처음 짠 코드
SELECT empno, ename, sal FROM emp
WHERE deptno IN (SELECT deptno FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp) and ename LIKE '%u%');

 

그런데 결과값은...

 

코드에 이상은 없는데 무엇이 잘못되었을까. 그래서 평균과 평균 급여보다 많은 급여를 받는 사원을 표시해보았다.

SELECT AVG(sal) FROM emp;
SELECT empno, ename, sal FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

평균 급여보다 많은 급여를 받는 사원 중에서 이름에 u가 포함된 직원이 없다!

 

위 코드를 '평균 급여보다 많은 급여를 받고 이름에 a가 포함된 사원'과 같은 부서에서 근무하는 모든 사원의 사원 번호, 이름 및 급여를 표시하는 것으로 바꿔서 출력해보았다.

-- 평균 급여보다 많은 급여를 받고 이름에 a가 포함된 사원
SELECT empno, ename, sal, deptno FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp) AND ename LIKE '%a%';

-- 그 사원들이랑 같은 부서(30, 10)에 속한 직원
SELECT empno, ename, sal, deptno FROM emp
WHERE deptno IN (SELECT deptno FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp) and ename LIKE '%a%');

 

아무리 봐도 코드가 잘못된 건 아닌 것 같았고 문제가 잘못되었나 싶어 학원 지인분께 어떻게 푸셨는지 여쭤봤다. 조건에 대한 해석이 나와 달랐다.

학원 지인분이 해석한 것 : 평균 급여보다 많은 급여를 받고 '이름에 u가 포함된 사원'과 같은 부서에서 근무하는 모든 사원의 사원 번호, 이름 및 급여를 표시하시오.

이렇게 되면 당연히 서브쿼리가 달라질 수밖에 없다. 학원 지인분 해석대로 문제를 풀어보았다.

 

-- 평균 급여(2073.214285714286)보다 많은 급여를 받는 직원
SELECT empno, ename, sal, deptno FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

-- 이름에 u가 포함된 사원
SELECT empno, ename, sal, deptno FROM emp
WHERE ename LIKE '%u%';

-- 평균 급여보다 많이 받으면서, TURNER와 같은 30번 부서인 사원
SELECT empno, ename, sal, deptno FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp) 
and deptno IN (SELECT deptno FROM emp WHERE ename LIKE '%u%');

 

국어의 중의적 의미 때문에 나와 학원 지인분의 서브쿼리가 달라질 수밖에 없었다. 내가 해석한 코드에서는 결과값이 null 뿐이고 강사님이 의도한 쪽은 학원 지인분이 해석한 쪽일 것 같아서 과제는 바꿔서 제출했다.

이번 건 프로그래밍에서의 오류가 아니라 의미 해석에서의 차이에 해당되고, 이런 걸 보면 SRS 문서가 왜 있는지 바로 알 것 같다. 클라이언트가 해석한 의미와 개발자가 해석한 의미가 다르면 당연히 문제가 생길 수밖에 없지.

 

각설하고, 전체 코드는 다음과 같다.

use scott;
SELECT * FROM emp;
SELECT * FROM dept;

-- 1. 'ACCOUNTING' 부서에서 근무하는 직원들의 이름, 급여, 입사일을 조회하시오.
SELECT ename, sal, HIREDATE FROM emp 
WHERE deptno = (SELECT deptno FROM dept WHERE dname = 'ACCOUNTING');

-- 2. 'TURNER'와 같은 부서에서 근무하는 직원의 이름과 부서번호를 조회하시오.
SELECT ename, deptno FROM emp 
WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'TURNER');

-- 3. 10번 부서의 평균급여보다 많은 급여를 받는 직원의 이름, 부서번호, 급여를 조회하시오.
SELECT ename, deptno, sal FROM emp 
WHERE sal > (SELECT AVG(sal) FROM emp GROUP BY deptno HAVING deptno = 10);

-- 4. King에게 보고하는 모든 사원의 이름과 급여를 표시하시오. 사원의 이름은 직원으로 Alias를 부여하시오
SELECT ename 직원, sal 급여 FROM emp 
WHERE mgr = (SELECT empno FROM emp WHERE ename = 'King');

-- 5. 평균 급여보다 많은 급여를 받고 이름에 u가 포함된 사원과 같은 부서에서 근무하는 모든 사원의 사원 번호, 이름 및 급여를 표시하시오
SELECT empno, ename, sal FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp) 
and deptno IN (SELECT deptno FROM emp WHERE ename LIKE '%u%');

-- 6. 평균 급여보다 높고 최대 급여보다 낮은 월급을 받는 사원의 정보를 조회하시오
SELECT * FROM emp 
WHERE sal > (SELECT AVG(sal) FROM emp)
AND sal < (SELECT MAX(sal) FROM emp);