[MySQL] NULL 처리 (IFNULL, CASE, COALESCE ...)

niz w·2025년 1월 13일

SQL

목록 보기
13/17

👉 IFNULL

IFNULL(컬럼명, "NULL 대체 값")

설정한 컬럼이 NULL인 경우 대체할 값을 설정할 수 있다!
Oracle은 NVL()을 사용하면 된다.


예를 들어,
SELECT * FROM activity_log WHERE session_end_time IS NULL AND id = "test";
id가 test인 사람의 활동 로그를 뽑는데, 그 중에 세션 종료 시간이 적히지 않은 데이터를 출력했다.


이렇게 데이터가 출력되는데... 이미지 속 log_id가 94~119인 test의 로그 기록의 종료시간을 현재 시간으로 대체해서 뽑아보겠다.

SELECT [다른 컬럼명...], IFNULL(session_end_time, CURRENT_TIMESTAMP) FROM activity_log WHERE log_id BETWEEN 94 AND 119 AND id = "test";


원래 종료 시간이 찍혀있던 데이터도 있었기에... 출력 행은 더 많아졌지만,
데이터를 전부 채워서 출력되었다.
기존에 종료 시간이 찍힌 데이터는 다른 행과 다르게 현재 시간이 아님을 알 수 있다.




👉 COALESCE

COALSECE(컬럼1, 컬럼1이 NULL인 경우 대체 값)
COALSECE(컬럼1, 컬럼2, 컬럼3, 컬럼4)

해당 함수는 지정한 표현식 중에서 NULL이 아닌 첫 번째 값을 반환한다.


위의 테이블로 예를 들어보려고 한다.

🎈 첫 번째는 컬럼1이 NULL인 경우 두 번째 값을 내놓게 된다.
SELECT id, title, COALESCE(nidkname, "익명의 회원") as name, content, created_at, updated_at FROM posts;

nickname이 없는 경우 "익명의 회원"으로 대체하는 것을 선택했더니,
1, 3번은 대체된 형태로 출력되었다.


🎈 두 번째는
컬럼1이 NULL인 경우 컬럼2를
컬럼2가 NULL인 경우 컬럼3을,
컬럼3이 NULL인 경우 컬럼4를 출력한다.

SELECT id, title, COALESCE(name, nickname, role, "익명의 회원") as name, content, created_at, updated_at FROM posts;

1, 2번 게시글name이 존재했기에 그대로 출력하고,
3번 게시글namenickname이 없지만 role이 존재하여 role이 대체하였다.

SELECT id, title, COALESCE(name, "익명의 회원", nickname, role) as name, content, created_at, updated_at FROM posts;
만약 name이 없는 경우 "익명의 회원" 출력을 우선순위로 둔다면,

name이 없는 3번 게시글"익명의 회원"이 출력된다.

대신, NULL이 아닌 값을 찾아 대체하는 것이므로
SELECT id, title, COALESCE(name, NULL, nickname, role) as name, content, created_at, updated_at FROM posts;
name을 대체할 값NULL로 설정했다면, 이 부분은 건너 뛰고 아래와 같이 출력된다.




👉 CASE문

CASE
  WHEN 조건1 THEN 출력값1
  WHEN 조건2 THEN 출력값2
  ELSE 출력값3
END AS 별칭

흔히 아는 if문 처럼 조건별로 출력값을 설정할 수 있다.

SELECT id, title, content,</code>
  CASE
    WHEN name IS NOT NULL THEN "이름 존재"
    WHEN nickname IS NOT NULL THEN "별명 존재"
    WHEN role IS NOT NULL THEN "역할 존재"
    ELSE "익명의 회원"
  END AS name
  , content, created_at, updated_at
FROM posts;


이름이 존재하는지, 별명이 존재하는지, 역할이 존재하는지 우선 순위를 두어 출력하는 쿼리를 작성해보았다.

if문도 첫 조건에 해당하면 다음의 else if문에 들어가지 않듯이 해당 구문도 동일하다.
두 번째 게시물의 작성자 데이터를 전부 삭제하면, role도 존재하지 않으므로 "익명의 회원"으로 출력됨을 알 수 있다.

as 별칭은 필요하지 않다면 설정하지 않아도 되며, 조건 부분에는 sub쿼리가 들어가기도 한다.




0개의 댓글