MS SQL의 STRING_SPLIT 함수는 문자열을 지정한 구분자 기준으로 나눈 결과를 반환한다. 그러나 STRING_SPLIT 함수는 결과의 출력 순서를 보장하지 않는, 즉 데이터베이스의 내부 구현 및 실행 계획에 따라 임의의 순서로 결과가 출력된다.
서비스를 운영하다보면 다른 기능에서 받은 파라미터 순서대로 결과를 출력해야 할 때가 있다.
만약 사용하는 SQL Server 버전이 2022라면 아래와 같이 새로 추가된 옵션(enable_ordinal)으로 출력 순서를 제어할 수 있을지 모른다.
STRING_SPLIT ( string , separator [ , enable_ordinal ] )
SELECT * FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ', 1);
하지만 내가 사용하고 있는 버전은 2022버전보다 낮기때문에 다른 방식을 찾아보았다.
1. ROW_NUMBER 사용하기
입력된 순서를 기억하기 위해 인덱스 또는 식별자를 포함한 결과를 만드는 방법이다.
DECLARE @str NVARCHAR(MAX) = '1,2,3,4,5,6,7,8,9,10,11,12';
DECLARE @delimiter NVARCHAR(1) = ',';
SELECT
value AS splitted_value,
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS idx
FROM
STRING_SPLIT(@str, @delimiter)
ORDER BY idx;
여기서 (SELECT NULL)은 정렬 조건으로 사용되는데, 실제로 정렬을 수행하지 않기 위해 사용한다. 즉 ROW_NUMBER() OVER (ORDER BY (SELECT NULL))는 정렬 조건이 필요하지 않는 순번을 할당하고자 할 때 사용되는 구문이다.
해당 구문을 이용하여 분할한 값에 대한 인덱스를 생성하고 order by절로 정렬한 것이다.
2. 테이블 변수 사용
두번째 방법은 테이블 변수를 생성하여 IDENTITY열을 추가하는 방법이다.
DECLARE @str NVARCHAR(MAX) = '1,2,3,4,5,6,7,8,9,10,11,12';
DECLARE @delimiter NVARCHAR(1) = ',';
DECLARE @resultTable TABLE
(
ID INT IDENTITY(1, 1),
Value NVARCHAR(100)
);
INSERT INTO @resultTable (Value)
SELECT value
FROM STRING_SPLIT(@str, @delimiter);
SELECT *
FROM @resultTable
ORDER BY ID;
IDENTITY 열과 값을 저장할 열을 포함한 테이블 변수를 생성하고, STRING_SPLIT 함수의 결과를 @resultTable에 저장한다.
이로 인해 STRING_SPLIT 함수의 결과를 테이블로 저장해서, IDENTITY 열을 통해 입력된 순서를 추적할 수 있게된다.
하지만 테이블 변수는 메모리에 저장되므로 대량의 데이터를 다룰 때는 메모리 부하가 발생할 수 있으니 주의하자.
'DataBase > mssql' 카테고리의 다른 글
[MSSQL] 컬럼 검색하기 (0) | 2023.07.05 |
---|---|
MSSQL : FORMAT함수 (0) | 2023.06.07 |
CONVERT, FORMAT함수 : 날짜(DATE) 포맷 변환 (0) | 2023.06.02 |
SQL Server의 OUTPUT 절: 데이터 변경 작업의 결과 추적 및 활용 (0) | 2023.05.23 |
MSSQL DATEDIFF 함수를 활용한 날짜 간격 계산 (1) | 2023.05.19 |