데이터베이스에서 쿼리를 실행하면 결과값은 보통 여러 행으로 나오게 됩니다.
컬럼으로 나오면 컬럼끼리 합치는 게 간단하지만 여러 행으로 나온 같은 컬럼을 합치기 위해서는 별도로 처리를 해줘야 합니다.
통계페이지 같은 경우 은근히 사용하게 되는 거 같네요.
함수를 사용하는 방법도 있고, 반복구문을 돌려서 하는 방법도 있고 해서 정리해 봅니다.
먼저 테스트 할 임시테이블과 데이터를 만들겠습니다. 필요없으신 분은 바로 아래로 스크롤 하세요~~ㅋ
CREATE TABLE #TMP (
Teams NVARCHAR(10),
PlayerName NVARCHAR(10),
BackNo INT,
IsRetire CHAR(1)
)
INSERT INTO #TMP VALUES('LG', '김현수', 22, 0)
INSERT INTO #TMP VALUES('LG', '박용택', 33, 1)
INSERT INTO #TMP VALUES('키움', '이정후', 51, 0)
INSERT INTO #TMP VALUES('두산', '박철순', 21, 1)
INSERT INTO #TMP VALUES('LG', '정우영', 18, 0)
INSERT INTO #TMP VALUES('두산', '이승엽', 77, 0)
INSERT INTO #TMP VALUES('LG', '고우석', 19, 0)
INSERT INTO #TMP VALUES('키움', '김혜성', 3, 0)
INSERT INTO #TMP VALUES('두산', '양의지', 25, 0)
이렇게 임시테이블을 만들어서 SELECT로 결과값을 보면,
아마도 이렇게 나오겠죠..??
원하는 결과값은 팀별로 은퇴하지 않은 소속선수와 그 선수의 등번호를 추출하는 것입니다.
3가지 방법을 진행 해 볼 생각인데요.. 성능까지는 잘 모르니 직접 확인해 주세요.. 저는 결과값 뽑는 것 만으로도 벅차서...ㅎㅎ
1. 반복문 활용
반복문을 사용하면 코드가 길어지는 단점이 있긴 한데, 별 고민없이 만들기는 괜찮은거 같네요.
DECLARE @TBL Table(Teams NVARCHAR(10), Players NVARCHAR(MAX))
SELECT Teams,
PlayerName + '(' + CONVERT(VARCHAR, BackNo) + ')' AS Players,
Row_Number() OVER(Partition by Teams Order by PlayerName ) AS CNT
INTO #Temp
FROM #TMP
WHERE IsRetire = 0
DECLARE @Cnt INT = 1
WHILE (1=1)
BEGIN
IF @Cnt = 1
BEGIN
INSERT @TBL
SELECT Teams, Players
FROM #Temp
WHERE CNT = @Cnt
END
ELSE
BEGIN
UPDATE @TBL
SET Players = A.Players + ', ' + B.Players
FROM @tbl A JOIN #Temp B ON A.Teams = B.Teams
WHERE B.CNT = @CNT
IF @@RowCount = 0 BREAK
END
SELECT @CNT = @CNT + 1
END
먼저 원하는 결과값의 대상들만 @TBL에 담아놓고, 반복해서 돌면서 업데이트 하는 구문입니다.
2. STUFF
먼저 STUFF 사용법을 정리하면,
STUFF( '대상문자열', 시작위치, 크기, '변경할문자' )
그리고 STUFF를 이용한 쿼리입니다. 반복문을 쓸때 보다는 훨씬 간단하네요.
SELECT DISTINCT Teams,
STUFF( (SELECT ', ' + PlayerName + '(' + CONVERT(VARCHAR, BackNo) + ')'
FROM #TMP
WHERE IsRetire = 0
AND A.Teams = Teams
ORDER BY PlayerName
FOR XML PATH('')), 1, 2, '') AS Players
FOR XML PATH가 데이터를 하나로 다 합치게 됩니다.
그리고 나서 맨 앞에 붙은 ', '를 STUFF를 이용해서 ''로 치환해서 없애버렸습니다.
이전에 가장 많이 사용하던 방식입니다.
3. STRING_AGG
마지막으로 STRING_AGG인데요. 이 방법은 MS-SQL 2017버전 부터 사용 가능합니다.
이전 버전에서는 작동하지 않으니 참고하시기 바랍니다.
STRING_AGG 사용법은
STRING_AGG('합칠컬럼명', '구분자' ) WITHIN GROUP(ORDER BY '컬럼명')
STRING_AGG를 사용한 코드는 제일 간단하네요. 역시 최신 버전!!!!
SELECT Teams,
STRING_AGG (PlayerName + '(' + CONVERT(VARCHAR, BackNo) + ')', ', ') WITHIN GROUP(ORDER BY PlayerName) AS Players
FROM #TMP
WHERE IsRetire = 0
GROUP BY Teams
이렇게 위의 3가지 방법을 다 실행하면.... 당연히 결과값은 동일하게 나옵니다..
아래의 그림 처럼...
이렇게 나오게 됩니다.(2022년 12월 현재 FA결과를 포함했습니다..ㅎㅎㅎ)
'Developer > DataBase' 카테고리의 다른 글
MSSQL SSMS 입력 시 자꾸 다른 문자로 변환될 때(한글 혹은 반자) (0) | 2023.10.27 |
---|---|
[MSSQL] 자주 쓰는 단축키 지정, 모음 (0) | 2023.08.24 |
[MS-SQL]프로시저, 테이블명 검색 (0) | 2022.12.12 |
MS-SQL 날짜 형태 변환함수 정리 (0) | 2019.12.11 |
MS-SQL 날짜함수 형식 변환 (0) | 2019.12.06 |