select문 질문입니다 0 2 1,189

by apptention [SQL Query] [2018.02.07 09:50:11]


-- 10명 이하만 입사한 년도별 부서이름 , 부서별 입사 사원수 
-- 아직 부서에 배치되지 않은 경우도 표시
-- 50번 부서는 제외

select to_Char(E.hire_date , 'yyyy') as hire_date , nvl(D.department_name,'**Undefined**') as department_name , count(E.employee_id) as cnt
from employees E , departments D
where E.department_id = D.department_id(+)
--and E.department_id != 50 -- <<< 1. 여기를 추가하면 department_id가 null인 결과가 사라집니다
group by to_Char(E.hire_date , 'yyyy') , nvl(D.department_name,'**Undefined**')
having count(E.employee_id) <= 10
order by department_name;

 

어디에 나와있는 문제는 아니구요 그냥 만들어본 문제입니다.

위 코드의 1부분을 추가하면 결과에서 department_id가 null인 결과가 사라집니다. 

그 이유와 해결 방법을 알고싶습니다.

by 마농 [2018.02.07 10:41:28]

1. null 을 비교하면 결과는 항상 false 이므로 널에 대한 처리가 필요
  - 변경전 : AND e.department_id != 50
  - 변경후 : AND NVL(e.department_id, 0) != 50
2. Group by 에서 NVL 사용은
  - 그룹바이에서 nvl 을 제거하고 select 절에서만 nvl 해도 결과는 같음
  - 그룹바이에서 nvl 하면 전체 사원수 만큼 nvl 처리를 하게 되는데
  - 그룹바이에서 nvl 을 제거하면 부서수 만큼만 NVL 하게 됨
  - NVL 반복 사용 제거 -> 쿼리가 간결해짐
  - NVL 사용 부하 감소
3. COUNT(e.employee_id) 는
  - 어차피 employee_id 는 널일 수 없으므로
  - COUNT(*) 로 바꾸는게 좋습니다.
  - COUNT(컬럼)을 하게 되면 컬럼이 널인지 아닌지 하나하나 체크하게 됩니다.
  - COUNT(*) 하면 체크 없이 그냥 카운트 하게 됩니다.
 

SELECT TO_CHAR(e.hire_date, 'yyyy') AS hire_date
     , NVL(d.department_name, '**Undefined**') AS department_name
     , COUNT(*) AS cnt
  FROM employees   e
     , departments d
 WHERE e.department_id = d.department_id(+)
   AND NVL(e.department_id, 0) != 50
 GROUP BY TO_CHAR(e.hire_date, 'yyyy')
     , d.department_name
HAVING COUNT(*) <= 10
 ORDER BY department_name
;

 


by apptention [2018.02.07 10:45:58]

질문에 +팁까지 정말 감사합니다 !!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입