테이블의 마지막 20개 레코드 중에서 무작위(random)로 5개를 추출하려면 서브쿼리와 함께 ORDER BY, RAND(), LIMIT를 조합하여 사용해야 합니다.
핵심 개념 정리
먼저 전체 로직을 이해하기 위해 각 절의 역할을 살펴보겠습니다.
- ORDER BY ... DESC LIMIT 20: 특정 컬럼 기준으로 내림차순 정렬한 뒤 마지막(최근) 20개 레코드만 가져옵니다.
- RAND(): 각 행에 무작위 값을 부여하여 결과 순서를 섞는 역할을 합니다.
- LIMIT 5: 섞인 결과 중 상위 5개만 최종적으로 반환합니다.
예제 테이블 생성
실습을 위해 먼저 테이블을 생성합니다.
mysql> create table DemoTable773 (StudentId int); Query OK, 0 rows affected (0.59 sec)
레코드 삽입
INSERT 명령어를 사용해 테이블에 데이터를 입력합니다.
mysql> insert into DemoTable773 values(100); Query OK, 1 row affected (0.15 sec) mysql> insert into DemoTable773 values(200); Query OK, 1 row affected (0.87 sec) mysql> insert into DemoTable773 values(300); Query OK, 1 row affected (1.59 sec) mysql> insert into DemoTable773 values(400); Query OK, 1 row affected (0.12 sec) mysql> insert into DemoTable773 values(500); Query OK, 1 row affected (0.29 sec) mysql> insert into DemoTable773 values(1); Query OK, 1 row affected (0.14 sec) mysql> insert into DemoTable773 values(2); Query OK, 1 row affected (0.17 sec) mysql> insert into DemoTable773 values(3); Query OK, 1 row affected (0.07 sec) mysql> insert into DemoTable773 values(4); Query OK, 1 row affected (0.73 sec) mysql> insert into DemoTable773 values(5); Query OK, 1 row affected (0.77 sec) mysql> insert into DemoTable773 values(6); Query OK, 1 row affected (0.20 sec) mysql> insert into DemoTable773 values(7); Query OK, 1 row affected (0.24 sec) mysql> insert into DemoTable773 values(8); Query OK, 1 row affected (0.50 sec) mysql> insert into DemoTable773 values(9); Query OK, 1 row affected (0.20 sec) mysql> insert into DemoTable773 values(10); Query OK, 1 row affected (0.23 sec) mysql> insert into DemoTable773 values(90); Query OK, 1 row affected (0.26 sec) mysql> insert into DemoTable773 values(91); Query OK, 1 row affected (0.11 sec) mysql> insert into DemoTable773 values(92); Query OK, 1 row affected (0.19 sec) mysql> insert into DemoTable773 values(93); Query OK, 1 row affected (0.33 sec) mysql> insert into DemoTable773 values(94); Query OK, 1 row affected (0.38 sec) mysql> insert into DemoTable773 values(95); Query OK, 1 row affected (0.34 sec) mysql> insert into DemoTable773 values(96); Query OK, 1 row affected (0.24 sec) mysql> insert into DemoTable773 values(97); Query OK, 1 row affected (0.27 sec)
전체 레코드 확인
SELECT 문으로 테이블의 모든 레코드를 조회합니다.
mysql> select *from DemoTable773;
실행 결과는 다음과 같습니다. 총 23개의 레코드가 저장되어 있습니다.
+-----------+ | StudentId | +-----------+ | 100 | | 200 | | 300 | | 400 | | 500 | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 | | 10 | | 90 | | 91 | | 92 | | 93 | | 94 | | 95 | | 96 | | 97 | +-----------+ 23 rows in set (0.00 sec)
마지막 20개 레코드에서 무작위 5개 추출하는 쿼리
이제 핵심 쿼리입니다. 내부 서브쿼리에서 StudentId를 기준으로 내림차순 정렬하여 마지막 20개 레코드를 먼저 선택하고, 외부 쿼리에서 RAND()로 순서를 섞은 후 LIMIT 5로 5개만 반환합니다.
mysql> select *from ( select * from DemoTable773 order by StudentId desc limit 20 ) AS RANDOM_OUTPUT order by rand() limit 5;
실행 결과 예시는 다음과 같습니다. 실행할 때마다 결과 조합은 달라지지만, 항상 마지막 20개 레코드 범위 내에서 5개가 추출됩니다.
+-----------+ | StudentId | +-----------+ | 95 | | 4 | | 10 | | 7 | | 300 | +-----------+ 5 rows in set (0.51 sec)
추가 팁: 성능 관련 참고 사항
ORDER BY RAND()는 대량의 데이터를 다룰 때 성능이 저하될 수 있습니다. 하지만 위 예제처럼 서브쿼리로 대상 레코드를 20개로 먼저 제한하기 때문에, 전체 테이블에 대해 RAND()를 적용하는 것보다 훨씬 효율적입니다. 실무에서도 이처럼 먼저 범위를 좁히고 난 뒤 무작위 추출을 적용하는 패턴을 권장합니다.