LIMIT & HAVING

Ryan·2025년 1월 15일

SQL/Python 분석

목록 보기
55/94

1. JOIN + GROUP BY 개념 미리 보기

  1. JOIN
    • 여러 테이블을 연결(Join)하여 데이터를 합쳐서, 더 풍부한 정보를 얻음.
    • 예) hr.hr_cate 테이블에는 부서 정보(Department), 교육 분야(EducationField) 등 속성 정보가 있고, hr.hr_number 테이블에는 직원 번호(EmployeeNumber) 등이 있을 수 있습니다.
    • 이 두 테이블을 연결하면, 부서별·교육분야별 인원수를 확인하는 통합 결과를 얻을 수 있습니다.
  2. GROUP BY
    • 특정 컬럼(예: 부서, 직무 등)을 기준으로 데이터 행을 그룹핑하고, 각 그룹에 대해 COUNT(*), SUM(), AVG()집계 함수를 적용해 결과를 뽑아냅니다.
    • 예) GROUP BY Department, EducationField → “(부서, 교육분야)” 조합으로 데이터를 묶고, 그 안에 속한 인원수를 계산.

2. JOIN된 테이블의 인원 데이터 집계하기

다음은 hr.hr_cate 테이블을 LEFT JOIN하여 hr.hr_number 테이블과 합친 뒤,

(부서, 교육분야) 조합별로 인원수를 세어보는 쿼리입니다:

sql
코드 복사
SELECT
    Department,
    EducationField,
    COUNT(*) AS hc
FROM hr.hr_cate hc
LEFT JOIN hr.hr_number hn
  ON hc.EmployeeNumber = hn.EmployeeNumber
GROUP BY 1,2;  -- 또는 GROUP BY Department, EducationField
  • COUNT(*) AS hc : 각 그룹(부서, 교육분야)에 해당하는 행의 개수를 hc라는 별칭으로 표시.
  • GROUP BY 1,2 : SELECT 절의 첫 번째 컬럼과 두 번째 컬럼(Department, EducationField)에 대해 그룹핑한다는 의미. (DBMS마다 문법 지원 여부가 다를 수 있으나, MySQL에서는 가능)
  • LEFT JOIN : hr.hr_cate(왼쪽 테이블)에 해당하는 레코드는 전부 가져오되, 오른쪽 hr.hr_number와 연결되지 않는 경우 NULL이 될 수 있음.

결과

  • DepartmentEducationField 조합별로 몇 명이 있는지 집계된 결과가 나온다.
  • 예) Sales + Marketing = 159명, Research & Development + Life Sciences = 440명 등.

3. 인원이 가장 많은 TOP 5 조합 뽑기

3-1. ORDER BY와 LIMIT 활용

집계 결과에서 가장 인원이 많은 상위 5개 (Department, EducationField) 조합을 보고 싶다면,

다음과 같이 ORDER BYLIMIT를 추가합니다:

sql
코드 복사
SELECT
    Department,
    EducationField,
    COUNT(*) AS hc
FROM hr.hr_cate hc
LEFT JOIN hr.hr_number hn
  ON hc.EmployeeNumber = hn.EmployeeNumber
GROUP BY 1,2
ORDER BY 3 DESC
LIMIT 5;
  • ORDER BY 3 DESC : SELECT 절의 세 번째 컬럼(hc)에 대해 내림차순 정렬
  • LIMIT 5 : 상위 5건만 가져오기

이렇게 하면 “인원이 가장 많은 (부서, 교육분야) 조합 TOP 5”가 조회됩니다.


4. 특정 조건의 그룹만 보려면? HAVING 절 사용

4-1. GROUP BY 결과에 대한 조건: HAVING

  • WHERE는 GROUP BY 이전에 레코드를 필터링하는 반면,
  • HAVINGGROUP BY 이후 집계된 결과에 대해 조건을 필터링할 때 사용합니다.

예) 부서-교육분야 그룹별 인원이 30명 이하인 그룹만 보고 싶다면:

sql
코드 복사
SELECT
    Department,
    EducationField,
    COUNT(*) AS hc
FROM hr.hr_cate hc
LEFT JOIN hr.hr_number hn
  ON hc.EmployeeNumber = hn.EmployeeNumber
GROUP BY 1,2
HAVING hc <= 30  -- 집계된 결과(hc)가 30 이하인 그룹만 필터링
ORDER BY hc DESC;
  • HAVING hc <= 30 : 집계 결과(hc)가 30 이하인 그룹만 남김
  • ORDER BY hc DESC : 인원수가 많은 순(내림차순)으로 보여주기
  • 따라서, 인원수가 최대 30명 이하인 부서-교육분야 그룹만 노출됩니다.

5. 쿼리 작성 시 주의사항 & 팁

  1. SELECT 절 vs. GROUP BY 절
    • 집계 함수(COUNT, SUM, AVG, etc.)가 아닌 칼럼들은 GROUP BY에 반드시 포함되어야 합니다.
    • 예) SELECT Department, EducationField, COUNT(*)GROUP BY Department, EducationField
  2. HAVING vs. WHERE
    • WHERE : 실제 행(row)을 그룹화하기 전에 필터링.
    • HAVING : 그룹화된 결과(집계값)에 대한 조건 필터링.
  3. JOIN 순서와 JOIN 종류
    • LEFT JOIN을 쓰는 이유? 왼쪽 테이블 기준으로 모든 레코드를 가져오되, 오른쪽에서 연결되는 데이터만 붙이기.
    • 만약 조인 결과를 엄격하게 두 테이블 모두 존재하는 행만 보려면 INNER JOIN을 사용.
  4. Alias
    • COUNT(*) AS hc처럼 집계 함수 결과에 별칭을 주면 ORDER BY나 HAVING에서 간편하게 사용할 수 있음.
    • 단, DBMS별로 ORDER BY 3 또는 ORDER BY hc와 같은 표현 지원 여부가 다를 수 있으니 주의.
  5. TOP N( LIMIT )
    • MySQL, MariaDB 등에서 지원.
    • Oracle이나 SQL Server 등은 ROWNUM, FETCH FIRST n ROWS 등을 사용.

6. 정리

  • JOIN + GROUP BY는 실무에서 거의 매일 쓰일 정도로 중요합니다.
    • 여러 테이블을 결합해서 원하는 정보를 갖춘 뒤,
    • 특정 기준으로 그룹핑하고 집계 함수(인원수, 매출액 등)를 구하는 패턴.
  • ORDER BY, LIMIT, HAVING 등을 조합해 “가장 많은 순/가장 적은 순/특정 범위 내” 그룹만 간단히 걸러낼 수 있습니다.
  • 쿼리 작성 시에는 집계된 값은 HAVING, 개별 행에 대한 조건은 WHERE로 구분하는 것이 핵심입니다.

이처럼 부서-교육분야별 인원수를 집계하고, 상위 5개를 구하거나 30명 이하만 필터링하는 등의 쿼리 방법은

데이터 분석과 리포팅에서도 자주 활용하므로 꼭 익혀두면 좋습니다.

0개의 댓글