Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL에서 날짜 내림차순 정렬 시 NULL(빈) 날짜를 마지막에 배치하는 방법

MySQL에서 날짜별로 정렬하되 NULL(빈) 날짜는 마지막에 배치하는 방법

MySQL에서 날짜 컬럼을 기준으로 데이터를 정렬할 때, 값이 없는(NULL) 행까지 함께 정렬해야 하는 경우가 자주 있습니다. 이럴 때 ORDER BY 절과 IS NULL 속성을 함께 사용하면 날짜순으로 정렬하면서도 빈 날짜(NULL)를 항상 목록의 맨 마지막에 배치할 수 있습니다.

기본 문법은 다음과 같습니다:

SELECT *FROM yourTableName
ORDER BY (yourDateColumnName IS NULL), yourDateColumnName DESC;

위 쿼리의 핵심은 (yourDateColumnName IS NULL) 부분입니다. MySQL에서 비교 연산의 결과는 0 또는 1로 반환되기 때문에, 값이 있는 행은 0, NULL인 행은 1로 평가됩니다. 이 표현식을 먼저 오름차순(기본값)으로 정렬하면 값이 있는 행이 모두 앞쪽에 오고, NULL 행은 자연스럽게 맨 뒤로 밀려납니다. 이후 두 번째 정렬 기준인 날짜 컬럼의 내림차순(DESC)으로 실제 정렬이 수행됩니다.

문법을 제대로 이해하기 위해 예제 테이블을 만들어 보겠습니다. 테이블 생성 쿼리는 다음과 같습니다:

mysql> create table DateColumnWithNullDemo
-> (
-> Id int NOT NULL AUTO_INCREMENT,
-> LoginDateTime datetime,
-> PRIMARY KEY(Id)
-> );
Query OK, 0 rows affected (0.84 sec)

이제 insert 명령을 사용해 샘플 데이터를 몇 개 삽입합니다. 의도적으로 NULL 값도 함께 넣었습니다:

mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(date_add(now(),interval -1 year));
Query OK, 1 row affected (0.15 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(NULL);
Query OK, 1 row affected (0.17 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(NULL);
Query OK, 1 row affected (0.12 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(now());
Query OK, 1 row affected (0.18 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(curdate());
Query OK, 1 row affected (0.23 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values('2017-08-25 15:30:35');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(NULL);
Query OK, 1 row affected (0.15 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values('2016-12-25 16:55:55');
Query OK, 1 row affected (0.15 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values(NULL);
Query OK, 1 row affected (0.22 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values('2014-11-12 10:20:23');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DateColumnWithNullDemo(LoginDateTime) values('2020-01-01 06:45:23');
Query OK, 1 row affected (0.23 sec)

select 문으로 테이블의 전체 레코드를 조회해 보겠습니다:

mysql> select *from DateColumnWithNullDemo;

실행 결과는 다음과 같습니다:

+----+---------------------+
| Id | LoginDateTime |
+----+---------------------+
| 1 | 2018-01-29 17:07:20 |
| 2 | NULL |
| 3 | NULL |
| 4 | 2019-01-29 17:07:54 |
| 5 | 2019-01-29 00:00:00 |
| 6 | 2017-08-25 15:30:35 |
| 7 | NULL |
| 8 | 2016-12-25 16:55:55 |
| 9 | NULL |
| 10 | 2014-11-12 10:20:23 |
| 11 | 2020-01-01 06:45:23 |
+----+---------------------+
11 rows in set (0.00 sec)

이제 NULL 값을 맨 마지막에 배치하면서 날짜를 내림차순으로 정렬하는 쿼리입니다:

mysql> select *from DateColumnWithNullDemo
-> order by (LoginDateTime IS NULL), LoginDateTime DESC;

실행 결과는 다음과 같습니다:

+----+---------------------+
| Id | LoginDateTime |
+----+---------------------+
| 11 | 2020-01-01 06:45:23 |
| 4 | 2019-01-29 17:07:54 |
| 5 | 2019-01-29 00:00:00 |
| 1 | 2018-01-29 17:07:20 |
| 6 | 2017-08-25 15:30:35 |
| 8 | 2016-12-25 16:55:55 |
| 10 | 2014-11-12 10:20:23 |
| 2 | NULL |
| 3 | NULL |
| 7 | NULL |
| 9 | NULL |
+----+---------------------+
11 rows in set (0.00 sec)

결과를 보면 최신 날짜부터 내림차순으로 정렬되고, NULL 값이었던 행(Id 2, 3, 7, 9)은 모두 목록의 맨 마지막에 배치된 것을 확인할 수 있습니다.

참고: 반대 경우의 처리

만약 오름차순 정렬 시 NULL을 마지막에 두고 싶다면 ORDER BY (LoginDateTime IS NULL), LoginDateTime ASC처럼 동일한 방식을 적용하면 됩니다. 반대로 NULL을 맨 앞에 배치하고 싶다면 ORDER BY (LoginDateTime IS NULL) DESC로 정렬 방향만 바꾸면 됩니다. 이처럼 IS NULL 표현식을 활용하면 별도의 CASE 문 없이도 간단하게 NULL 정렬 위치를 제어할 수 있습니다.