데이터베이스(쉬운코드)
9. SQL로 데이터 조회하기 5부 : grouping, ordering
youbing
2024. 12. 5. 14:23
본 내용은 유튜버 쉬운코드의 강의 "데이터베이스"를 참고하여 작성하였습니다.
order by
- 조회 결과를 특정 attribute(s) 기준으로 정렬하여 가져오고 싶을 때 사용한다.
- default 정렬 방식은 오름차순이다.
- 오름차순 정렬은 ASC, 내림차순 정렬은 DESC로 표기한다.
예제 : 임직원들의 정보를 연봉 순서대로 정렬해서 알고 싶다.
SELECT * FROM employee ORDER BY salary [DESC];
-- 부서별로 묶어서 연봉순으로 보고 싶으면
SELECT * FROM employee ORDER BY dept_id ASC, salary DESC;
- ASC로 정렬하면 NULL이 가장 먼저 뜸.
aggregate function
- 여러 tuple들의 정보를 요약해서 하나의 값으로 추출하는 함수
- 대표적으로 COUNT, SUM, MAX, MIN, AVG 함수가 있다.
- (주로) 관심있는 attribute에 사용된다. e.g) AVG(salary), MAX(birth_date)
- NULL 값들은 제외하고 요약 값을 추출한다.
예제 1 : 임직원 수를 알고 싶다.
SELECT COUNT(*) FROM employee;
- COUNT는 중복도 세기 때문에 COUNT(position)을 하더라도 동일한 결과가 나옴.
- 그러나 NULL은 세지 않음.
- 그래서 테이블의 튜플 수를 세고 싶은 것이라면 COUNT(*)를 추천
예제 2 : 프로젝트 2002에 참여한 임직원 수/최대 연봉/최소 연봉/평균 연봉을 알고 싶다.
SELECT COUNT(*), MAX(salary), MIN(salary), AVG(salary)
FROM employee E JOIN works_on W ON E.id = W.empl_id
WHERE W.proj_id = 2002;
group by
예제 2-1 : 각 프로젝트에 참여한 임직원 수/최대 연봉/최소 연봉/평균 연봉을 알고 싶다.
SELECT W.proj_id, COUNT(*), MAX(salary), MIN(salary), AVG(salary)
FROM employee E JOIN works_on W ON E.id = W.empl_id
GROUP BY W.proj_id;
- 어떤 프로젝트에 따른 결과인지 알기 위해 W.proj_id도 같이 출력 -> GROUP BY에 쓴 속성을 꼭 같이 출력해줘야 함.
- WHERE W.proj_id = 2002 대신 GROUP BY W.proj_id로 변경
GROUP BY
- 관심있는 attribute(s) 기준으로 그룹을 나눠서 그룹별로 aggregate fct을 적용하고 싶을 때 사용
- grouping attribute(s) : 그룹을 나누는 기준이 되는 attribute(s)
- grouping attribute(s)에 NULL 값이 있을 때는 NULL 값을 가지는 tuple끼리 묶인다.
having
예제 2-2 : 프로젝트 참여 인원이 7명 이상인 프로젝트들에 대해서 각 프로젝트에 참여한 임직원 수/최대 연봉/최소 연봉/평균 연봉을 알고 싶다.
SELECT W.proj_id, COUNT(*), MAX(salary), MIN(salary), AVG(salary)
FROM employee E JOIN works_on W ON E.id = W.empl_id
GROUP BY W.proj_id
HAVING COUNT(*) >= 7;
- GROUP BY와 함께 사용한다.
- aggregate fct의 결과값을 바탕으로 그룹을 필터링하고 싶을 때 사용한다.
- HAVING절에 명시된 조건을 만족하는 그룹만 결과에 포함된다.
예1 (group by + order by)
예제 1 : 각 부서별 인원수를 인원 수가 많은 순서대로 정렬해서 알고 싶다.
SELECT dept_id, COUNT(*) AS empl_count FROM employee
GROUP BY dept_id
ORDER BY empl_count DESC;
예제 1-1 : 각 부서별-성별 인원수를 인원 수가 많은 순서대로 정렬해서 알고 싶다.
SELECT dept_id, sex, COUNT(*) AS empl_count FROM employee
GROUP BY dept_id, sex
ORDER BY empl_count DESC;
예2 (group by + having + subquery)
예제 : 회사 전체 평균 연봉보다 평균 연봉이 적은 부서들의 평균 연봉을 알고 싶다.
SELECT dept_id, AVG(salary) AS dept_salary FROM employee
GROUP BY dept_id
HAVING dept_salary < (SELECT AVG(salary) FROM employee);
예3 (group by + order by + having + subquery)
예제 1 : 각 프로젝트별로 프로젝트에 참여한 90년대생들의 수와 이들의 평균 연봉을 알고 싶다.
SELECT W.proj_id, COUNT(*), ROUND(AVG(E.salary), 0)
FROM employee E JOIN works_on W ON E.id = W.empl_id
WHERE E.birth_date between'1990-01-01' AND '1999-12-31'
GROUP BY W.proj_id;
- 이 상태에서 proj_id 순으로 정렬하고 싶으면 ORDER BY W.proj_id 추가
예제 1-1 : 프로젝트 참여 인원이 7명 이상인 프로젝트에 한정해서 각 프로젝트별로 프로젝트에 참여한 90년대생들의 수와 이들의 평균 연봉을 알고 싶다.
- 위의 코드에서 HAVING COUNT(*) >= 7 추가하면 90년대생 참여 인원이 7명 이상인 프로젝트 한정이 되기 때문에 안됨. -> WHERE 절에 조건을 추가해야 함.
SELECT W.proj_id, COUNT(*), ROUND(AVG(E.salary), 0)
FROM employee E JOIN works_on W ON E.id = W.empl_id
WHERE E.birth_date between'1990-01-01' AND '1999-12-31'
AND W.proj_id IN (SELECT proj_id FROM works_on GROUP BY proj_id HAVING COUNT(*) >= 7)
GROUP BY W.proj_id;
select 요약 & 실행 순서
SELECT attribute(s) or aggregate fct(s) -- 6
FROM table(s) -- 1
[WHERE condition(s)] -- 2
[GROUP BY group attribute(s)] -- 3
[HAVING group condition(s)] -- 4
[ORDER BY attribute(s)] -- 5
- select 쿼리에서 각 절(phrase)의 실행 순서는 개념적인 순서이다
- select 쿼리의 실제 실행 순서는 각 RDBMS에서 어떻게 구현했는지에 따라 다르다.
참고 사항
1. 오늘 내용은 MySQL 기준입니다. 다른 RDBMS의 SQL 문법은 조금씩 다를 수 있습니다.
2. 오늘 영상은 ordering, grouping 관련하여 대표적으로 중요한 기본기들을 살펴봤습니다. 디테일한 내용들은 추가적으로 공부하시는 것이 필요합니다.