데이터베이스 관리 및 분석을 하다 보면, 특정 조건에 맞는 데이터를 집계해야 하는 경우가 자주 발생합니다. 이번 포스팅에서는 SQL을 사용하여 특정 테이블에서 중복된 이름을 찾고, 그 빈도를 계산하는 쿼리를 살펴보겠습니다.
아래와 같은 테이블이 주어졌을 때,
동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성해주세요. 이때 결과는 이름이 없는 동물은 집계에서 제외(IS NOT NULL)하며, 결과는 이름 순으로 조회(ORDER BY) 해주세요.
다음은 ANIMAL_INS 테이블에서 중복된 이름을 찾아 그 빈도를 출력하는 SQL 쿼리입니다:
SELECT NAME, COUNT(NAME) AS COUNT
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME;
- SELECT: 필요한 컬럼을 선택합니다. 여기서는 NAME과 그 이름의 빈도 수를 반환하는 COUNT(NAME) AS COUNT를 선택했습니다.
- FROM: 데이터를 조회할 테이블을 지정합니다. 여기서는 ANIMAL_INS 테이블을 사용합니다.
- WHERE: 특정 조건을 만족하는 행만 조회합니다. 여기서는 NAME이 NULL이 아닌 행만 선택합니다.
- GROUP BY: 이름별로 데이터를 그룹화합니다. 즉, 같은 이름을 가진 행들이 하나의 그룹으로 묶입니다.
- HAVING: 그룹화된 결과 중에서 조건을 만족하는 그룹만 선택합니다. 여기서는 COUNT(NAME)이 2 이상인 그룹만 선택합니다.
- ORDER BY: 결과를 정렬합니다. 여기서는 NAME 기준으로 오름차순 정렬합니다.
상세 설명
- SELECT 및 COUNT:
- SELECT NAME, COUNT(NAME) AS COUNT는 NAME 컬럼과 각 이름의 빈도 수를 조회합니다. COUNT(NAME)는 각 이름의 개수를 세며, 이를 COUNT라는 별칭으로 반환합니다.
- FROM:
- FROM ANIMAL_INS는 데이터를 조회할 테이블을 지정합니다. 이 테이블에는 동물의 입소 정보가 저장되어 있다고 가정합니다.
- WHERE:
- WHERE NAME IS NOT NULL는 이름이 NULL이 아닌 행만 선택합니다. 이는 이름이 없는 행을 제외하고 분석을 진행하기 위함입니다.
- GROUP BY:
- GROUP BY NAME는 같은 이름을 가진 행들을 하나의 그룹으로 묶습니다. 이렇게 하면 각 이름별로 그룹화되어 각 그룹의 빈도를 계산할 수 있습니다.
- HAVING:
- HAVING COUNT(NAME) >= 2는 그룹화된 결과 중에서 빈도가 2 이상인 그룹만 선택합니다. 이는 중복된 이름을 찾기 위한 조건입니다.
- ORDER BY:
- ORDER BY NAME는 결과를 이름 기준으로 오름차순 정렬합니다. 이를 통해 결과를 정렬된 형태로 쉽게 확인할 수 있습니다.
SQL 쿼리 작성 순서와 실행 순서
작성 순서:
SQL 쿼리를 작성할 때는 일반적으로 다음 순서로 작성합니다:
- SELECT: 반환할 컬럼을 지정합니다.
- FROM: 데이터를 조회할 테이블을 지정합니다.
- WHERE: 행을 필터링합니다.
- GROUP BY: 행을 그룹화합니다.
- HAVING: 그룹화된 결과를 필터링합니다.
- ORDER BY: 결과를 정렬합니다.
실행 순서:
SQL 쿼리가 실제로 실행되는 순서는 다릅니다. 데이터베이스 엔진이 쿼리를 처리하는 순서는 다음과 같습니다:
- FROM: 데이터를 조회할 테이블을 결정하고 조인(join) 연산이 있다면 이를 수행합니다.
- WHERE: 테이블에서 조건에 맞는 행을 필터링합니다.
- GROUP BY: 필터링된 행을 그룹화합니다.
- HAVING: 그룹화된 결과에 조건을 적용하여 필터링합니다.
- SELECT: 최종적으로 반환할 컬럼을 선택합니다.
- ORDER BY: 결과를 정렬합니다.
이 차이를 이해하는 것은 쿼리를 최적화하고, 예상치 못한 결과를 방지하는 데 중요합니다.
GROUP BY와 HAVING의 작동 원리
GROUP BY
GROUP BY 절은 SELECT 쿼리에서 동일한 값을 가진 여러 행을 하나의 그룹으로 묶습니다. 이를 통해 각 그룹에 대해 집계 함수(예: COUNT, SUM, AVG 등)를 사용할 수 있습니다.
SELECT NAME, COUNT(*)
FROM ANIMAL_INS
GROUP BY NAME;
이 쿼리는 ANIMAL_INS 테이블에서 각 NAME별로 그룹을 만들고, 각 그룹에 속하는 행의 수를 세어 반환합니다.
HAVING
HAVING 절은 GROUP BY 절로 그룹화된 결과에 대해 조건을 적용합니다. WHERE 절이 그룹화 전에 행을 필터링하는 데 사용된다면, HAVING 절은 그룹화된 후의 결과에 조건을 적용합니다.
SELECT NAME, COUNT(*)
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(*) >= 2;
이 쿼리는 각 NAME별로 그룹을 만든 후, 각 그룹의 행 수가 2 이상인 경우만 결과에 포함시킵니다.
예제 쿼리의 실행 과정
아래는 예제 쿼리가 실제로 실행되는 순서를 설명합니다:
SELECT NAME, COUNT(NAME) AS COUNT
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME;
실행 과정:
- FROM ANIMAL_INS:
- ANIMAL_INS 테이블에서 모든 데이터를 가져옵니다.
- WHERE NAME IS NOT NULL:
- NAME이 NULL이 아닌 행을 필터링합니다.
- GROUP BY NAME:
- NAME별로 행을 그룹화합니다.
- HAVING COUNT(NAME) >= 2:
- 각 그룹의 행 수가 2 이상인 그룹만 선택합니다.
- SELECT NAME, COUNT(NAME) AS COUNT:
- 각 그룹의 NAME과 그 그룹의 행 수를 선택합니다.
- ORDER BY NAME:
- 결과를 NAME 기준으로 오름차순 정렬합니다.
정리
SQL 쿼리를 작성할 때와 실제로 실행될 때의 순서를 이해하는 것은 매우 중요합니다. 다음과 같은 요점을 기억하세요:
- 작성 순서: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY
- 실행 순서: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY
이 순서를 이해하면 쿼리의 작동 방식을 더 잘 이해할 수 있고, 이를 통해 보다 효율적인 쿼리를 작성할 수 있습니다.
'Programming > SQL' 카테고리의 다른 글
[TIL 0627] SUBQUERY (스칼라 서브쿼리) (0) | 2024.06.27 |
---|---|
[TIL 0626] GROUP BY 와 HAVING (0) | 2024.06.26 |
[TIL 0626][SQL] MySQL 쿼리를 작성할 때 따옴표를 붙여줘야 하는 경우 (0) | 2024.06.26 |
[프로그래머스 SQL] 문제풀이 (정렬, 중복제거) (0) | 2024.06.25 |
[TIL 0624][SQL] DBeaver 를 통해 느낀점. (0) | 2024.06.24 |