여러 개의 행과 쉼표없이 COALESCE를 사용하는 방법은 무엇입니까?


27

다음을 달성하려고합니다.

California | Los Angeles, San Francisco, Sacramento
Florida    | Jacksonville, Miami

불행히도 "로스 앤젤레스, 샌프란시스코, 새크라멘토, 잭슨빌, 마이애미"

STUFF 기능을 사용하여 원하는 결과를 얻을 수 있지만 COALESCE를 사용하여 더 깨끗한 방법이 있는지 궁금합니다.

STATE       | CITY
California  | San Francisco
California  | Los Angeles
California  | Sacramento
Florida     | Miami
Florida     | Jacksonville 


DECLARE @col NVARCHAR(MAX);
SELECT @col= COALESCE(@col, '') + ',' + city
FROM tbl where city = 'California';
SELECT @col;

감사

답변:


45

이것은 당신이 추구하는 더 깨끗한 접근법 일 수 있습니다. 기본적으로 변수가 아직 초기화되었는지 확인하십시오. 그렇지 않은 경우 빈 문자열로 설정하고 첫 번째 도시 (앞에 쉼표 없음)를 추가하십시오. 있는 경우 쉼표를 추가 한 다음 도시를 추가하십시오.

DECLARE @col nvarchar(MAX);
SELECT @col = COALESCE(@col + ',', '') + city
  FROM dbo.tbl WHERE state = 'California';

물론 상태마다 변수를 채우는 경우에만 작동합니다. 한 번에 하나씩 각 상태의 목록을 가져 오는 경우 한 번에 더 나은 솔루션이 있습니다.

SELECT [state], cities = STUFF((
    SELECT N', ' + city FROM dbo.tbl
    WHERE [state] = x.[state]
    FOR XML PATH(''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 2, N'')
FROM dbo.tbl AS x
GROUP BY [state]
ORDER BY [state];

결과 :

state       cities
----------  --------------------------------------
California  San Francisco, Los Angeles, Sacramento  
Florida     Miami, Jacksonville

각 주 내에서 도시 이름으로 주문하려면 :

SELECT [state], cities = STUFF((
    SELECT N', ' + city FROM dbo.tbl
    WHERE [state] = x.[state]
    ORDER BY city
    FOR XML PATH(''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 2, N'')
FROM dbo.tbl AS x
GROUP BY [state]
ORDER BY [state];

Azure SQL Database 또는 SQL Server 2017+ 에서 새로운 STRING_AGG()기능을 사용할 수 있습니다 .

SELECT [state], cities = STRING_AGG(city, N', ')
  FROM dbo.tbl
  GROUP BY [state]
  ORDER BY [state];

그리고 도시 이름으로 주문 :

SELECT [state], cities = STRING_AGG(city, N', ') 
                         WITHIN GROUP (ORDER BY city)
  FROM dbo.tbl
  GROUP BY [state]
  ORDER BY [state];

고마워 Aaron. 현재 솔루션은 GROUP BY 대신 DISTINCT를 사용한다는 점을 제외하고는 거의 동일합니다.
user2732180

2
@ user2732180 상태 당 한 번 연결을 수행 할 가능성이 높으므로 GROUP BY를 사용해야합니다. DISTINCT를 사용하면 예를 들어 캘리포니아의 모든 인스턴스에 동일한 연결을 적용한 다음 복제본을 생성 한 모든 작업 만 버립니다.
Aaron Bertrand

6

그냥에 추가 아론의 대답 위 ...

ORDER BY검색어에 마지막 항목 만 포함하면 오류 가 발생할 수 있습니다. 내 경우에는 그룹화하지 않았으므로 차이가 있는지 확실하지 않습니다. SQL 2014를 사용하고 있습니다. 필자의 경우 value1, value2, value3 ...과 같은 것이 있지만 변수의 결과는 value3뿐입니다.


아론은 다음과 같이 말했습니다.

Connect에서 최소 네 번보고되었습니다.

  1. 변수 연결 및 필터 별 순서로 결과 (예 : 조건)
  2. (n) ORDER BY가 추가되면 ResultSet에서 varchar 작성에 실패
  3. CROSS APPLYs 및 테이블 반환 함수를 사용하여 정렬 된 SELECT에서 로컬 변수를 할당하면 마지막 값만 반환
  4. 테이블 변수에서 varchar (max) / nvarchar (max) 값을 연결할 때 기본 키가 아닌 열을 기준으로 필터링하고 정렬하면 잘못된 결과가 반환 될 수 있습니다.

Microsoft의 응답 예 :

보고있는 동작은 의도적으로 설계된 것입니다. ORDER BY 절이있는 쿼리에서 할당 작업 (이 예에서는 연결)을 사용하면 동작이 정의되지 않습니다.

응답은 또한 KB 287515를 참조합니다.

PRB : 식 계획에 따라 실행 계획 및 집계 연결 쿼리 결과

FOR XML PATH연결 순서가 중요하고 물론 모든 값을 포함하려는 경우 해결책은 (Aaron의 대답에서 두 번째 접근법 )을 사용 하는 것입니다. 참조 :

스택 오버플로에서 nvarchar 연결 / 인덱스 / nvarchar (max) 설명 할 수없는 동작

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.