Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

MySQL에서 ORDER BY RAND()로 정렬하면서 그룹 유지하기

테이블 생성

먼저 실습에 사용할 테이블을 만들어 보겠습니다.

mysql> create table DemoTable
    -> (
    -> StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> StudentMarks int
    -> );
Query OK, 0 rows affected (0.58 sec)

샘플 데이터 삽입

INSERT 명령으로 레코드를 추가합니다. 그룹화 효과를 확인할 수 있도록 동일한 점수(98, 78)를 가진 중복 레코드도 일부러 함께 넣었습니다.

mysql> insert into DemoTable(StudentMarks) values(98);
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable(StudentMarks) values(98);
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable(StudentMarks) values(78);
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable(StudentMarks) values(78);
Query OK, 1 row affected (0.29 sec)
mysql> insert into DemoTable(StudentMarks) values(45);
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable(StudentMarks) values(56);
Query OK, 1 row affected (0.09 sec)

저장된 데이터 확인

SELECT 문으로 테이블의 전체 레코드를 조회합니다.

mysql> select *from DemoTable;

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

+-----------+--------------+
| StudentId | StudentMarks |
+-----------+--------------+
| 1         | 98           |
| 2         | 98           |
| 3         | 78           |
| 4         | 78           |
| 5         | 45           |
| 6         | 56           |
+-----------+--------------+
6 rows in set (0.00 sec)

그룹을 유지한 채 무작위 정렬하기

행마다 완전히 섞는 것이 아니라, 같은 점수끼리 묶인 상태에서 그룹 단위의 순서만 무작위로 바꾸고 싶다면 아래 쿼리처럼 RAND()에 시드 값을 활용하면 됩니다.

mysql> select *from DemoTable order by rand(StudentMarks*100*RAND());

실행 결과를 보면 점수가 98점인 두 레코드(StudentId 1번, 2번)가 여전히 인접한 채 그룹으로 유지되면서, 전체 행의 순서만 무작위로 섞인 것을 확인할 수 있습니다.

+-----------+--------------+
| StudentId | StudentMarks |
+-----------+--------------+
| 3         | 78           |
| 6         | 56           |
| 5         | 45           |
| 4         | 78           |
| 1         | 98           |
| 2         | 98           |
+-----------+--------------+
6 rows in set (0.00 sec)

동작 원리와 참고 사항

여기서 핵심은 MySQL에서 RAND()에 인자를 전달하면 해당 값이 시드(seed)로 사용되어 결정적인 의사 난수를 반환한다는 점입니다. 위 쿼리에서는 StudentMarks * 100 * RAND()를 시드로 사용하기 때문에, 동일한 점수를 가진 행들이 서로 연관된 정렬 키를 갖게 되고 그 결과 그룹이 흩어지지 않고 유지됩니다.

다만 ORDER BY RAND()는 모든 행에 대해 난수를 계산한 후 정렬을 수행하기 때문에, 데이터 양이 많은 테이블에서는 성능 부담이 커질 수 있습니다. 대량 데이터 환경에서는 임시 테이블 활용이나 애플리케이션 단계에서의 셔플 처리 등 다른 방식을 함께 고려하는 것이 좋습니다.