복붙노트

[SQL] STRING_AGG에서 고유 값을 생성합니다

SQL

STRING_AGG에서 고유 값을 생성합니다

내가 COUNT와 같은 효과를 만들 싶습니다 SQL 서버 2017에서 STRING_AGG 기능을 사용하고 있습니다 (DISTINCT <칼럼>). 나는 시도 STRING_AGG (DISTINCT <열>, ',')하지만 법적 구문이 아닙니다.

나는 작업 주위에 T-SQL이 있는지 알고 싶습니다. 여기 내 샘플입니다 :

WITH Sitings 
  AS
  (
    SELECT * FROM (VALUES 
      (1, 'Florida', 'Orlando', 'bird'),
      (2, 'Florida', 'Orlando', 'dog'),
      (3, 'Arizona', 'Phoenix', 'bird'),
      (4, 'Arizona', 'Phoenix', 'dog'),
      (5, 'Arizona', 'Phoenix', 'bird'),
      (6, 'Arizona', 'Phoenix', 'bird'),
      (7, 'Arizona', 'Phoenix', 'bird'),
      (8, 'Arizona', 'Flagstaff', 'dog')
    ) F (ID, State, City, Siting)
  ) 
SELECT State, City, COUNT(DISTINCT Siting) [# Of Types], STRING_AGG(Siting,',') Animals
FROM Sitings 
GROUP BY State, City

위는 다음과 같은 결과를 생성합니다 :

+---------+-----------+--------------+-------------------------+
|  State  |   City    | # Of Types   |         Animals         |
+---------+-----------+--------------+-------------------------+
| Arizona | Flagstaff |            1 | dog                     |
| Florida | Orlando   |            2 | dog,bird                |
| Arizona | Phoenix   |            2 | bird,bird,bird,dog,bird |
+---------+-----------+--------------+-------------------------+

출력은 내가 이런 식으로, DISTINCT로 피닉스 애리조나에 대해 나열된 연결된 "동물"원하는 제외하고 내가 원하는 것을 정확히 :

+---------+-----------+--------------+--------------------+
|  State  |   City    | # Of Types   |      Animals       |
+---------+-----------+--------------+--------------------+
| Arizona | Flagstaff |            1 | dog                |
| Florida | Orlando   |            2 | dog,bird           |
| Arizona | Phoenix   |            2 | bird,dog           |
+---------+-----------+--------------+--------------------+

어떤 아이디어?

내가 훨씬 더 큰 내 실제 데이터 세트를 사용하는 경우, 나는 8000 개 문자를 초과하는 "동물"칼럼에 대한 오류가 발생합니다.

내 예는 훨씬 간단 제외하고 내가 생각하는 내 질문이 하나와 동일합니다.

해결법

  1. ==============================

    1.여기 한 가지 방법이다.

    여기 한 가지 방법이다.

    당신은뿐만 아니라 별개의 수를 원하기 때문에, 그것은 두 번 행을 그룹화하여 간단하게 수행 할 수 있습니다. 중복 제거 제 BY 그룹이 제 2 그룹 BY는 최종 결과를 생성한다.

    WITH
    Sitings
    AS
    (
        SELECT * FROM (VALUES 
        (1, 'Florida', 'Orlando', 'bird'),
        (2, 'Florida', 'Orlando', 'dog'),
        (3, 'Arizona', 'Phoenix', 'bird'),
        (4, 'Arizona', 'Phoenix', 'dog'),
        (5, 'Arizona', 'Phoenix', 'bird'),
        (6, 'Arizona', 'Phoenix', 'bird'),
        (7, 'Arizona', 'Phoenix', 'bird'),
        (8, 'Arizona', 'Flagstaff', 'dog')
        ) F (ID, State, City, Siting)
    )
    ,CTE_Animals
    AS
    (
        SELECT
            State, City, Siting
        FROM Sitings
        GROUP BY State, City, Siting
    )
    SELECT
        State, City, COUNT(1) AS [# Of Sitings], STRING_AGG(Siting,',') AS Animals
    FROM CTE_Animals
    GROUP BY State, City
    ORDER BY
        State
        ,City
    ;
    

    결과

    +---------+-----------+--------------+----------+
    |  State  |   City    | # Of Sitings | Animals  |
    +---------+-----------+--------------+----------+
    | Arizona | Flagstaff |            1 | dog      |
    | Arizona | Phoenix   |            2 | bird,dog |
    | Florida | Orlando   |            2 | bird,dog |
    +---------+-----------+--------------+----------+
    

    당신은 여전히 ​​8000자를 초과에 대한 오류 메시지가 표시되는 경우, STRING_AGG 전에 VARCHAR (최대)에 값을 캐스팅.

    같은 뭔가

    STRING_AGG(CAST(Siting AS varchar(max)),',') AS Animals
    
  2. ==============================

    2.단지 사용하는 서브 쿼리

    단지 사용하는 서브 쿼리

    WITH Sitings 
          AS
          (
            SELECT * FROM (VALUES 
              (1, 'Florida', 'Orlando', 'bird'),
              (2, 'Florida', 'Orlando', 'dog'),
              (3, 'Arizona', 'Phoenix', 'bird'),
              (4, 'Arizona', 'Phoenix', 'dog'),
              (5, 'Arizona', 'Phoenix', 'bird'),
              (6, 'Arizona', 'Phoenix', 'bird'),
              (7, 'Arizona', 'Phoenix', 'bird'),
              (8, 'Arizona', 'Flagstaff', 'dog')
            ) F (ID, State, City, Siting)
          ) 
    
        select State,City,count(*) as [# Of Types],STRING_AGG(Siting,',') AS Animals from 
        (
          SELECT State, City, Siting
        FROM Sitings 
        GROUP BY State, City,Siting
        ) as T  group by State,City
    

    http://sqlfiddle.com/#!18/ba4b8/11

      State     City    # Of Types  Animals
    Arizona     Flagstaff   1   dog
    Florida     Orlando     2   bird,dog
    Arizona     Phoenix     2   bird,dog
    
  3. ==============================

    3.물론 매우 늦게 응답의.

    물론 매우 늦게 응답의.

    이것은 또 다른 방법입니다. STRING_AGG의 부지 (부지 선정은, ',') 그룹화 키는 주 및 도시 일치 앉아 반환 된 DISTINCT 목록에 subqueried 할 수 있습니다.

    WITH Sitings 
          AS
          (
            SELECT * FROM (VALUES 
              (1, 'Florida', 'Orlando', 'bird'),
              (2, 'Florida', 'Orlando', 'dog'),
              (3, 'Arizona', 'Phoenix', 'bird'),
              (4, 'Arizona', 'Phoenix', 'dog'),
              (5, 'Arizona', 'Phoenix', 'bird'),
              (6, 'Arizona', 'Phoenix', 'bird'),
              (7, 'Arizona', 'Phoenix', 'bird'),
              (8, 'Arizona', 'Flagstaff', 'dog')
            ) F (ID, State, City, Siting)
          ) 
    
    SELECT 
        S.State, 
        S.City, 
        COUNT(DISTINCT S.Siting) AS [# Of Types],
    
        --STRING_AGG(S.Siting,',') AS Animals
        (
            SELECT STRING_AGG(U.SITING, ',')
            FROM 
            (
                SELECT DISTINCT T.Siting
                FROM Sitings AS T
                WHERE 
                    T.State = S.State AND
                    T.City = S.City
            ) AS U
        ) AS ANIMAL
    
    FROM 
        Sitings AS S
    GROUP BY 
        S.State, 
        S.City
    ORDER BY
        S.State, 
        S.City
    
  4. from https://stackoverflow.com/questions/51646385/produce-distinct-values-in-string-agg by cc-by-sa and MIT license