[SQL] Count문 다양하게 사용하기

유알·2024년 6월 9일
0

[SQL]

목록 보기
2/2

지금까지는 Count 문을 단순히 특정 컬럼이나 레코드를 세는 용도로만 사용했다.
최근에 다양한 사용방법을 마주치면서 지금까지 발견한 사용법을 정리하고자 글을 쓴다.
다른 집계쿼리도 충분히 활용가능할 것이다.

모든 행 수 세기

SELECT COUNT(*) 
FROM ...

이렇게 되면, 모든 행의 수를 세게 된다.

NULL 이 아닌 컬럼 세기

특정 칼럼명을 명시해주면, 그 컬럼이 Null일때는 세지 않는다

SELECT
    COUNT(*),
    COUNT(age)
FROM (
    SELECT
        null as age ,'James' as name
     )

유니크한 컬럼 세기

distinct 절을 내부에 사용할 수 있다. 그러면 해당 컬럼의 유니크한 집합을 구해준다.

INSERT INTO users (name, age)
VALUES ('Alice', 25),
       ('Bob', 30),
       ('Charlie', 35),
       ('David', 40),
       ('Eve', 45),
       ('Frank', 50),
       ('Grace', 55),
       ('Hannah', 60),
       ('Ivy', 65),
       ('Jack', 70);

SELECT
    COUNT(DISTINCT age / 10) as age_group_count,
    COUNT(age) as total_count
FROM users;

이런식으로 응용하면 20, 30, 40, 50, 60, 70 대로 6개가 나온다. 4개의 중복이 제거 되었기 때문이다.

특정 조건에 만족하는 값들만 세기

SELECT
    COUNT(CASE WHEN age > 40 THEN 1 END) as over_40
FROM users;

여기서는 CASE WHEN문을 활용하였다.
CASE WHEN 에서 ELSE문을 지정하지 않았으므로, 조건에 해당하지 않으면 NULL이 되므로 카운트가 되지 않는다.

저 THEN 뒤에 2를 넣던 -1을 넣던 결과가 동일하다. 조건에 따라 가중 카운트를 하고 싶으면, SUM을 사용해야한다.
가중평균도 가능할 것이다.

SELECT
    COUNT(CASE WHEN age > 40 THEN 1 END) as over_40,
    AVG(age) as avg_age,
    AVG(CASE WHEN age > 40 THEN age + 10 ELSE age END) as weighted_avg_age
FROM users;

윈도우 함수, 그룹바이 함수

over partition by 를 활용해서 특정 그룹당 값을 추가하거나, group by를 사용해서 그룹핑할 수도 있다.

SELECT
    name,
    age,
    age / 10 AS age_group,
    COUNT(age) OVER(PARTITION BY age/10) as count
FROM users
ORDER BY age_group;

그룹바이와 비슷하지만, 값들이 집합당으로 표시되지 않는다.

SELECT
    row_number() over (ORDER BY age / 10) as row_number,
    age / 10 AS age_group,
    COUNT(*) AS count
FROM users
GROUP BY age_group
ORDER BY row_number;

이렇게도 사용해 보았다. 이 경우, partition by와 다르게 집합별로 값이 그룹핑된다.

profile
더 좋은 구조를 고민하는 개발자 입니다

0개의 댓글