MySQL COUNT(DISTINCT) 설명: 고유 값을 효율적으로 세는 방법

目次

1. 소개

데이터베이스를 관리할 때 “등록된 국가가 몇 개입니까?” 혹은 “고유한 이메일 주소가 몇 개입니까?”와 같은 상황에 직면할 수 있습니다. 이러한 경우 MySQL의 COUNT(DISTINCT column_name)을 사용하여 중복을 제거하면서 레코드 수를 가져올 수 있습니다.

이 문서에서는 다음 주제들을 자세히 설명합니다:

  • COUNT()DISTINCT의 기본
  • COUNT(DISTINCT column_name)의 올바른 사용법
  • 여러 컬럼에 걸친 고유 값 계산 방법
  • COUNT(DISTINCT) 성능 향상 방법

초보자도 실용적인 예제와 SQL 쿼리를 통해 쉽게 이해할 수 있도록 설명합니다. 끝까지 꼭 읽어보세요.

2. MySQL에서 데이터 카운팅 기본 (COUNT)

데이터베이스에서 데이터를 분석할 때 가장 기본적인 함수는 COUNT()입니다. 먼저 COUNT()가 어떻게 작동하는지 이해해 봅시다.

2.1 COUNT(*)와 COUNT(column_name)의 차이

MySQL의 COUNT() 함수는 다음 두 가지 방식으로 사용할 수 있습니다:

COUNT FunctionDescription
COUNT(*)Counts all records in the table (including NULL values)
COUNT(column_name)Counts non-NULL values in a specific column

2.2 기본 COUNT() 예제

여기서는 다음 users 테이블을 예시로 사용합니다:

idnameemailcountry
1Tarotaro@example.comJapan
2Hanakohanako@example.comJapan
3JohnNULLUnited States
4Tanakatanaka@example.comJapan

① 테이블의 전체 레코드 수 가져오기

SELECT COUNT(*) FROM users;

→ 결과: 4 (전체 레코드 수)

② 특정 컬럼의 NULL이 아닌 값 개수 가져오기

SELECT COUNT(email) FROM users;

→ 결과: 3 (email 컬럼의 NULL이 아닌 값 개수)

💡 핵심 포인트:

  • COUNT(*)NULL 값을 포함한 전체 레코드 수를 반환합니다.
  • COUNT(email)은 카운트 시 NULL 값을 제외합니다.

3. 중복 없는 데이터 조회 (DISTINCT)

데이터를 집계할 때 고유한 값만 조회하고 싶을 때가 많습니다. 이런 경우 DISTINCT가 매우 유용합니다.

3.1 DISTINCT 기본

DISTINCT는 지정된 컬럼에서 중복 데이터를 제거하고 고유한 결과를 반환하는 데 사용됩니다.

기본 구문

SELECT DISTINCT column_name FROM table_name;

3.2 DISTINCT 사용 예시

다음 SQL 쿼리를 실행하면 사용자가 등록한 고유한 국가 이름 목록을 가져올 수 있습니다.

SELECT DISTINCT country FROM users;

→ 결과:

country
Japan
United States

3.3 DISTINCT와 GROUP BY의 차이

FeatureDISTINCTGROUP BY
PurposeRetrieve unique valuesPerform aggregation by group
UsageSELECT DISTINCT column_nameSELECT column_name, COUNT(*) GROUP BY column_name
ExampleRetrieve unique countriesCount users per country

💡 핵심 포인트:

  • DISTINCT는 단순히 중복 데이터를 제거합니다.
  • GROUP BY는 데이터를 그룹화하고 집계 함수와 함께 사용됩니다.

4. COUNT(DISTINCT column_name) 사용 방법

COUNT(DISTINCT column_name)를 사용하면 고유 값의 개수를 가져올 수 있습니다.

4.1 COUNT(DISTINCT) 기본

기본 구문

SELECT COUNT(DISTINCT column_name) FROM table_name;

4.2 COUNT(DISTINCT) 예시

SELECT COUNT(DISTINCT country) FROM users;

→ 결과: 2 (두 종류: “Japan”과 “United States”)

4.3 조건과 함께 COUNT(DISTINCT) 사용

SELECT COUNT(DISTINCT email) FROM users WHERE country = 'Japan';

→ 결과: 2 (일본에 등록된 고유 email 값 개수)

💡 핵심 포인트:

  • COUNT(DISTINCT column_name)NULL 값을 제외하고 고유 데이터만 카운트합니다.
  • WHERE 절을 사용하면 특정 조건을 만족하는 레코드를 카운트할 수 있습니다.

5. 여러 컬럼과 함께 COUNT(DISTINCT) 사용

MySQL에서는 COUNT(DISTINCT column1, column2)를 직접 사용할 수 없습니다. 대신 일반적인 해결책은 CONCAT()을 사용해 컬럼을 결합하고 하나의 값으로 취급하는 것입니다.

5.1 COUNT(DISTINCT column1, column2)를 사용할 수 없는 이유

MySQL에서는 다음과 같이 여러 컬럼에 COUNT(DISTINCT)를 직접 적용할 수 없습니다: COUNT(DISTINCT column1, column2). 이는 MySQL의 제한 때문입니다.

5.2 여러 컬럼의 고유 조합을 카운트하는 방법

여러 열의 고유한 조합을 세기 위해, 일반적인 접근 방식은 CONCAT()을 사용하여 열을 결합한 후 결과에 COUNT(DISTINCT)를 적용하는 것입니다.

예시: 국가와 도시의 고유 조합 세기

SELECT COUNT(DISTINCT CONCAT(country, '-', city)) FROM users;

💡 핵심 포인트:

  • CONCAT(column1, '-', column2)를 사용하면 여러 열을 단일 고유 값으로 결합할 수 있습니다.
  • COUNT(DISTINCT CONCAT(...))를 사용하면 여러 열에 걸친 고유 조합의 수를 검색할 수 있습니다.

6. COUNT(DISTINCT)에 대한 성능 튜닝

COUNT(DISTINCT)는 성능에 영향을 미칠 수 있으므로 최적화가 필요할 수 있습니다.
대규모 데이터셋을 다룰 때는 인덱스 사용이나 대안 접근 방식을 고려하는 것이 좋습니다.

6.1 COUNT(DISTINCT)가 느려질 수 있는 이유

  • MySQL은 DISTINCT를 적용하기 위해 종종 모든 레코드를 스캔합니다.
  • 인덱스가 제대로 구성되지 않으면 쿼리 실행이 느려집니다.
  • 중복 데이터의 양이 많으면 계산 부하가 증가합니다.

6.2 COUNT(DISTINCT) 속도를 높이기 위한 인덱스 최적화

대량의 데이터를 처리할 때, 대상 열에 인덱스를 추가하여 쿼리 성능을 개선할 수 있습니다.

인덱스 추가 방법

ALTER TABLE users ADD INDEX (country);

인덱스를 사용한 쿼리 실행 계획 확인

EXPLAIN SELECT COUNT(DISTINCT country) FROM users;

💡 핵심 포인트:

  • EXPLAIN을 사용하면 MySQL이 쿼리를 어떻게 처리하는지 확인할 수 있습니다.
  • 인덱스를 적용하면 전체 테이블 스캔을 피하고 검색 성능을 개선할 수 있습니다.

6.3 대안 방법: GROUP BY + COUNT

집계 요구사항에 따라 GROUP BY를 사용하면 더 나은 성능을 제공할 수 있습니다.

예시: GROUP BY를 사용한 고유 데이터 세기

SELECT country, COUNT(*) FROM users GROUP BY country;

💡 핵심 포인트:

  • GROUP BY는 일부 경우에 COUNT(DISTINCT)보다 더 나은 성능을 제공할 수 있습니다.
  • 데이터를 동시에 그룹화하고 집계해야 할 때 특히 유용합니다.

7. COUNT(DISTINCT)의 일반적인 오류와 해결책

COUNT(DISTINCT)를 사용할 때 여러 일반적인 오류를 만날 수 있습니다.
여기서는 전형적인 문제와 그 해결책을 소개합니다.

7.1 오류 1: COUNT(DISTINCT column1, column2)를 사용할 수 없음

오류 원인

MySQL에서 여러 열을 대상으로 할 때 COUNT(DISTINCT column1, column2)는 지원되지 않습니다.
이 구문을 직접 사용하면 오류가 발생합니다.

해결책: CONCAT() 사용

여러 열을 결합한 후 결과에 COUNT(DISTINCT)를 적용하여 이 오류를 피할 수 있습니다.

SELECT COUNT(DISTINCT CONCAT(country, '-', city)) FROM users;

💡 핵심 포인트:

  • CONCAT(column1, '-', column2)를 사용하면 여러 열에서 고유 값을 생성할 수 있습니다.
  • COUNT(DISTINCT CONCAT(...))를 사용하면 각 조합에 대한 고유 값을 검색할 수 있습니다.

7.2 오류 2: NULL 값이 포함될 때 예상치 못한 결과

오류 원인

  • COUNT(DISTINCT column_name)NULL 값을 무시하므로, 열에 NULL이 포함되어 있으면 예상치 못한 결과가 발생할 수 있습니다.

해결책: IFNULL() 사용

NULL을 다른 기본값(예: '' 또는 'unknown')으로 대체하여 올바른 카운팅을 보장할 수 있습니다.

SELECT COUNT(DISTINCT IFNULL(email, 'unknown')) FROM users;

💡 핵심 포인트:

  • IFNULL(column_name, 'default_value')를 사용하면 NULL 값을 적절히 처리할 수 있습니다.

7.3 오류 3: COUNT(DISTINCT)가 느림

오류 원인

  • COUNT(DISTINCT)모든 데이터를 스캔하므로 대규모 데이터셋에서 성능이 느려질 수 있습니다.

해결책: 인덱스 사용

ALTER TABLE users ADD INDEX (country);

💡 핵심 포인트:

  • 인덱스를 추가하면 쿼리 성능이 개선될 수 있습니다.
  • EXPLAIN을 사용해 쿼리 최적화 상태를 확인하세요.
    EXPLAIN SELECT COUNT(DISTINCT country) FROM users;
    

By applying these measures, you can enhance the practicality of COUNT(DISTINCT) and avoid performance issues.

8. 자주 묻는 질문 (FAQ)

다음은 COUNT(DISTINCT)에 대한 자주 묻는 질문들입니다.

8.1 COUNT(*)COUNT(DISTINCT column_name)의 차이점은 무엇인가요?

핵심 차이점

FunctionDescription
COUNT(*)Counts all records (including NULL values)
COUNT(DISTINCT column_name)Counts unique values (excluding NULL values)

사용 예시

SELECT COUNT(*) FROM users;
SELECT COUNT(DISTINCT email) FROM users;

💡 핵심 포인트:

  • COUNT(*) 모든 레코드를 카운트합니다.
  • COUNT(DISTINCT column_name) 고유 값의 개수를 반환합니다 (NULL 제외).

8.2 DISTINCTGROUP BY의 차이점은 무엇인가요?

FeatureDISTINCTGROUP BY
PurposeRetrieve unique valuesPerform aggregation by group
UsageSELECT DISTINCT column_nameSELECT column_name, COUNT(*) GROUP BY column_name
ExampleRetrieve unique countriesCount users per country

사용 예시

-- Using DISTINCT
SELECT DISTINCT country FROM users;

-- Using GROUP BY
SELECT country, COUNT(*) FROM users GROUP BY country;

💡 핵심 포인트:

  • DISTINCT 단순히 중복 데이터를 제거합니다.
  • GROUP BY 데이터를 그룹화하고 집계 함수와 결합할 수 있습니다.

8.3 COUNT(DISTINCT)는 느린가요?

문제

  • COUNT(DISTINCT) 전체 데이터를 스캔 하므로, 대용량 데이터셋에서는 성능이 저하될 수 있습니다.

해결책: 인덱스 사용

ALTER TABLE users ADD INDEX (country);

대안 접근법: GROUP BY 사용

SELECT country, COUNT(*) FROM users GROUP BY country;

💡 핵심 포인트:

  • 인덱스를 적용하면 검색 성능이 향상될 수 있습니다.
  • 경우에 따라 GROUP BY를 사용하면 COUNT(DISTINCT)보다 더 빠른 결과를 얻을 수 있습니다.

8.4 COUNT(DISTINCT column1, column2)를 어떻게 사용할 수 있나요?

문제

  • MySQL에서는 COUNT(DISTINCT column1, column2)를 지원하지 않습니다.

해결책: CONCAT() 사용

SELECT COUNT(DISTINCT CONCAT(country, '-', city)) FROM users;

💡 핵심 포인트:

  • CONCAT(column1, '-', column2)를 사용하면 여러 컬럼에 걸쳐 고유 값을 생성할 수 있습니다.
  • COUNT(DISTINCT CONCAT(...))를 사용하면 고유한 조합을 조회할 수 있습니다.

이 질문들을 참고하면 COUNT(DISTINCT)를 보다 효율적으로 사용할 수 있습니다.

9. 결론

이 기사에서는 MySQL의 COUNT(DISTINCT) 함수 사용 방법을 자세히 설명했습니다.
핵심 요점을 다시 살펴보겠습니다.

9.1 이 기사에서 배운 내용

MySQL에서 레코드를 카운트하는 방법

  • COUNT(*)는 전체 레코드 수를 반환합니다
  • COUNT(column_name)는 NULL을 제외한 값을 카운트합니다
  • COUNT(DISTINCT column_name)는 고유 값의 개수를 반환합니다

DISTINCTCOUNT(DISTINCT)의 차이점

  • DISTINCT는 중복이 제거된 데이터를 반환합니다
  • COUNT(DISTINCT column_name)는 고유 값의 개수를 카운트합니다

여러 컬럼과 함께 COUNT(DISTINCT)를 사용하는 방법

  • MySQL이 COUNT(DISTINCT column1, column2)를 직접 지원하지 않으므로, 대신 CONCAT()을 사용합니다

성능 최적화 기법

  • 인덱스 적용으로 검색 성능을 향상시킵니다
  • 적절한 경우 GROUP BY + COUNT를 사용하여 더 빠른 쿼리를 수행합니다

9.2 이 지식을 활용해 할 수 있는 일

이 지식을 적용하면 다음과 같은 데이터 집계를 수행할 수 있습니다:
🔹 고유 사용자 수 카운트
🔹 특정 조건에 따른 레코드 수 조회
🔹 여러 컬럼에 걸친 고유 데이터 카운트
🔹 대용량 데이터셋에 대한 쿼리 최적화

MySQL에서 데이터 집계 및 최적화를 수행할 때, 이 가이드를 참고하십시오!