programing

SQL Server에서 STRING_AGG를 사용하여 고유 값 가져오기

codeshow 2023. 10. 4. 23:05
반응형

SQL Server에서 STRING_AGG를 사용하여 고유 값 가져오기

다음 쿼리는 아래에 표시된 결과를 반환합니다.

SELECT 
    ProjectID, newID.value
FROM 
    [dbo].[Data] WITH(NOLOCK)  
CROSS APPLY 
    STRING_SPLIT([bID],';') AS newID  
WHERE 
    newID.value IN ('O95833', 'Q96NY7-2') 

결과:

ProjectID   value
---------------------
2           Q96NY7-2
2           O95833
2           O95833
2           Q96NY7-2
2           O95833
2           Q96NY7-2
4           Q96NY7-2
4           Q96NY7-2

새로 추가된 것 사용하기STRING_AGG함수(SQL Server 2017에서) 아래 쿼리에 나와 있는 것처럼 아래 결과 집합을 얻을 수 있습니다.

SELECT 
    ProjectID,
    STRING_AGG( newID.value, ',') WITHIN GROUP (ORDER BY newID.value) AS 
NewField
FROM
    [dbo].[Data] WITH(NOLOCK)  
CROSS APPLY 
    STRING_SPLIT([bID],';') AS newID  
WHERE 
    newID.value IN ('O95833', 'Q96NY7-2')  
GROUP BY 
    ProjectID
ORDER BY 
    ProjectID

결과:

ProjectID   NewField
-------------------------------------------------------------
2           O95833,O95833,O95833,Q96NY7-2,Q96NY7-2,Q96NY7-2
4           Q96NY7-2,Q96NY7-2

저는 최종 출력물에 아래와 같은 고유한 요소만 포함했으면 합니다.

ProjectID   NewField
-------------------------------
2           O95833, Q96NY7-2
4           Q96NY7-2

이 결과를 얻는 방법에 대한 제안이 있습니까?필요한 경우 언제든지 제 쿼리를 처음부터 다시 다듬거나 재디자인하십시오.

사용.DISTINCT결과를 결합하기 전에 중복을 제거하는 하위 쿼리의 키워드: SQL Fiddle

SELECT 
ProjectID
,STRING_AGG(value, ',') WITHIN GROUP (ORDER BY value) AS 
NewField
from (
    select distinct ProjectId, newId.value 
    FROM [dbo].[Data] WITH(NOLOCK)  
    CROSS APPLY STRING_SPLIT([bID],';') AS newID  
    WHERE newID.value IN (   'O95833' , 'Q96NY7-2'  )  
) x
GROUP BY ProjectID
ORDER BY ProjectID

OP Title: 개선을 환영합니다!에 답하는 함수입니다.

CREATE OR ALTER FUNCTION [dbo].[fn_DistinctWords]
(
  @String NVARCHAR(MAX)  
)
RETURNS NVARCHAR(MAX)
WITH SCHEMABINDING
AS
BEGIN
  DECLARE @Result NVARCHAR(MAX);
  WITH MY_CTE AS ( SELECT Distinct(value) FROM STRING_SPLIT(@String, ' ')  )
  SELECT @Result = STRING_AGG(value, ' ') FROM MY_CTE
  RETURN @Result
END
GO

다음과 같이 사용:

SELECT dbo.fn_DistinctWords('One Two      Three Two One');

사용가능distinct에 사용되는 서브쿼리에서.apply:

SELECT d.ProjectID,
       STRING_AGG(  newID.value, ',') WITHIN GROUP (ORDER BY newID.value) AS 
NewField
FROM [dbo].[Data] d CROSS APPLY
     (select distinct value
      from STRING_SPLIT(d.[bID], ';') AS newID 
     ) newID
WHERE newID.value IN (   'O95833' , 'Q96NY7-2'  ) 
group by projectid;

@SeanLange가 댓글에서 지적했듯이, 이것은 데이터를 꺼내는 끔찍한 방법이지만, 필요하다면 다음과 같이 두 개의 개별 쿼리를 만들어 주십시오.

SELECT 
    ProjectID
    ,STRING_AGG( val, ',') WITHIN GROUP (ORDER BY val) AS NewField
FROM
(
    SELECT DISTINCT 
        ProjectID
        ,newID.value AS val
    FROM 
        [dbo].[Data] WITH(NOLOCK)  
        CROSS APPLY STRING_SPLIT([bID],';') AS newID  
    WHERE 
        newID.value IN ('O95833' , 'Q96NY7-2') 
) t
GROUP BY
    ProjectID

그 정도면 됐다.

@ttugates에 대한 개선점을 소개합니다.

CREATE OR ALTER FUNCTION [dbo].[fn_DistinctList]
(
  @String NVARCHAR(MAX),
  @Delimiter char(1)
)
RETURNS NVARCHAR(MAX)
WITH SCHEMABINDING
AS
BEGIN
  DECLARE @Result NVARCHAR(MAX);
  WITH MY_CTE AS ( SELECT Distinct(value) FROM STRING_SPLIT(@String, 
@Delimiter)  )
  SELECT @Result = STRING_AGG(value, @Delimiter) FROM MY_CTE
  RETURN @Result
END

또 다른 가능성은 그들로부터 독특한 문자열을 얻을 수 있습니다.STRING_AGG쉼표로 구분된 문자열을 가져온 후 다음 세 단계를 수행합니다.

  1. 문자열 분할(STRING_SPLIT)
  2. 선택한다.DISTINCT갈라진 틈을 타서
  3. 적용합니다.STRING_AGG단일 키에 그룹이 있는 선택 항목으로 다시 이동

예:

(select STRING_AGG(CAST(value as VARCHAR(MAX)), ',') 
        from (SELECT distinct 1 single_key, value 
            FROM STRING_SPLIT(STRING_AGG(CAST(customer_division as VARCHAR(MAX)), ','), ',')) 
                q group by single_key) as customer_division

집계 값을 저장하는 테이블의 고유한 보기를 만들 수 있으며, 이는 더욱 간단합니다.

Create Table Test (field1 varchar(1), field2 varchar(1));

go

Create View DistinctTest as (Select distinct field1, field2 from test group by field1,field2);

go

insert into Test Select 'A', '1';
insert into Test Select 'A', '2';
insert into Test Select 'A', '2';
insert into Test Select 'A', '2';
insert into Test Select 'D', '1';
insert into Test Select 'D', '1';

select string_agg(field1, ',')  from Test where field2 = '1';  /* duplicates: A,D,D */;

select string_agg(field1, ',')  from DistinctTest where field2 = '1';  /* no duplicates: A,D  */;

Oracle(버전 19c 이후) 지원 listagg (DISTINCT ..., 하지만 마이크로소프트 SQL 서버는 아마 아닐 겁니다.

언급URL : https://stackoverflow.com/questions/50589064/get-unique-values-using-string-agg-in-sql-server

반응형