복붙노트

[SQL] PIVOT 동적에서 반환 된 결과는 두 개의 테이블을 조인

SQL

PIVOT 동적에서 반환 된 결과는 두 개의 테이블을 조인

내가 아주 간단한 쿼리라고 생각하는 것은 내가 예상 다음 무엇을 조금 더 까다로운 일이 될 것으로 보인다.

나는 두 개의 테이블이있다. 일대 다 관계로. 내가 뭘하려고 나는 그것이 별도의 열에되고 싶은 테이블이에 의해 반환 된 기록이다. 나는 상대적으로 작은 데이터로이 다음 쿼리에서 그것을 할 관리 및 2 차 테이블에 의해 반환되는 것을 알 수있다.

샘플 데이터

DECLARE @TABLE1 TABLE(UserID INT,Episode INT ,[Value] VARCHAR(100))
INSERT INTO @TABLE1 VALUES
(1, 1,'VALUE 1-1'),(1, 2,'VALUE 1-2')

DECLARE @TABLE2 TABLE(UserID INT,Episode INT ,[Details] VARCHAR(100))
INSERT INTO @TABLE2 VALUES
(1, 1,'Details 1'),(1, 1,'Details 2'),(1, 2,'Details 1'),(1, 2,'Details 2') 

간단한 가입

SELECT  ONE.UserID
      , ONE.Episode
      , ONE.Value
      , TWO.Details 
FROM @TABLE1 ONE INNER JOIN @TABLE2 Two
ON ONE.UserID = TWO.UserID 
AND ONE.Episode = TWO.Episode

╔════════╦═════════╦═══════════╦═══════════╗
║ UserID ║ Episode ║   Value   ║  Details  ║
╠════════╬═════════╬═══════════╬═══════════╣
║      1 ║       1 ║ VALUE 1-1 ║ Details 1 ║
║      1 ║       1 ║ VALUE 1-1 ║ Details 2 ║
║      1 ║       2 ║ VALUE 1-2 ║ Details 1 ║
║      1 ║       2 ║ VALUE 1-2 ║ Details 2 ║
╚════════╩═════════╩═══════════╩═══════════╝

이 경우 나는 세부 열을 선회하고 싶습니다. 다음과 같이 나는 매우 간단 PIVOT 쿼리와 함께 할 관리 어떤

PIVOT 쿼리

SELECT * FROM
(
SELECT  ONE.UserID
      , ONE.Episode
      , ONE.Value
      , TWO.Details 
FROM @TABLE1 ONE INNER JOIN @TABLE2 Two
ON ONE.UserID = TWO.UserID AND ONE.Episode = TWO.Episode)Q
PIVOT (MAX(Details)
       FOR Details
       IN ([Details 1], [Details 2]))p

╔════════╦═════════╦═══════════╦═══════════╦═══════════╗
║ UserID ║ Episode ║   Value   ║ Details 1 ║ Details 2 ║
╠════════╬═════════╬═══════════╬═══════════╬═══════════╣
║      1 ║       1 ║ VALUE 1-1 ║ Details 1 ║ Details 2 ║
║      1 ║       2 ║ VALUE 1-2 ║ Details 1 ║ Details 2 ║
╚════════╩═════════╩═══════════╩═══════════╩═══════════╝

이 정확히 내가 원하는, 그래서에 대한 자세한 사항 1, 자세한 사항 2 및 세부 3로 명명 된 열 테이블이에서 반환 된 모든 기록 ...

데이터 자체가 "자세한 사항 1", "자세한 사항 2"와 "세부 3"와 같은 문자열입니다 재곡 때문에이 경우에는했다.

그러나 때 나는 표 2에서 반환되는 행 수를 잘 모릅니다과 내가 그 선회에 어려움을 겪고하고있는 데이터가 될 것입니다.

하나 개 더 중요한 것은 테이블이에서 반환 된 데이터가 연결된 몇 개의 컬럼으로 구성 큰 텍스트 값 것입니다.

나는이에 주어진 논리를 질문하지만 기쁨이 본을 따르도록 노력했다.

올바른 방향으로 어떤 포인터가 많이 감사합니다 어떤 도움이 사전에 감사합니다.

해결법

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

    1.어쩌면 내가 뭔가를 놓친 거지하지만 당신은 PIVOT에 데이터 수 있어야하지만 당신은 열을 생성하는 데 도움을 ROW_NUMBER ()를 구현해야합니다.

    어쩌면 내가 뭔가를 놓친 거지하지만 당신은 PIVOT에 데이터 수 있어야하지만 당신은 열을 생성하는 데 도움을 ROW_NUMBER ()를 구현해야합니다.

    열쇠는 유사한 쿼리를 사용하는 것입니다 :

    SELECT  ONE.UserID,
      ONE.Episode,
      ONE.Value,
      TWO.Details,
      'Details'
        +cast(row_number() over(partition by one.userid, one.episode
                               order by two.details) as varchar(10)) seq
    FROM TABLE1 ONE 
    INNER JOIN TABLE2 Two
      ON ONE.UserID = TWO.UserID 
    AND ONE.Episode = TWO.Episode
    

    이 새로운 열의 이름의 고유 한 시퀀스를 생성합니다, 당신은 PIVOT을 적용 할 수 있습니다 :

    select userid, episode,
      value,
      details1,
      details2
    from
    (
      SELECT  ONE.UserID,
        ONE.Episode,
        ONE.Value,
        TWO.Details,
        'Details'
          +cast(row_number() over(partition by one.userid, one.episode
                                  order by two.details) as varchar(10)) seq
      FROM TABLE1 ONE 
      INNER JOIN TABLE2 Two
        ON ONE.UserID = TWO.UserID 
      AND ONE.Episode = TWO.Episode
    ) d
    pivot
    (
      max(details)
      for seq in (Details1, Details2)
    ) piv;
    

    데모와 SQL 바이올린을 참조하십시오. 그럼 당신은 동적 SQL이 변환 할 수 있습니다 :

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT ',' + QUOTENAME('Details'+cast(seq as varchar(10))) 
                        from 
                        (
                          select 
                            row_number() over(partition by one.userid, one.episode
                                                    order by two.details) seq
                            FROM TABLE1 ONE 
                            INNER JOIN TABLE2 Two
                              ON ONE.UserID = TWO.UserID 
                            AND ONE.Episode = TWO.Episode
                        ) d
                        group by seq
                        order by seq
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = 'SELECT userid, episode, value, ' + @cols + ' 
                from 
                (
                 SELECT  ONE.UserID,
                    ONE.Episode,
                    ONE.Value,
                    TWO.Details,
                    ''Details''
                      +cast(row_number() over(partition by one.userid, one.episode
                                              order by two.details) as varchar(10)) seq
                  FROM TABLE1 ONE 
                  INNER JOIN TABLE2 Two
                    ON ONE.UserID = TWO.UserID 
                  AND ONE.Episode = TWO.Episode
                ) x
                pivot 
                (
                    max(details)
                    for seq in (' + @cols + ')
                ) p '
    
    execute sp_executesql @query;
    

    데모와 SQL 바이올린을 참조하십시오. 당신에게 결과를주기 :

    | USERID | EPISODE |     VALUE |  DETAILS1 |  DETAILS2 |
    |--------|---------|-----------|-----------|-----------|
    |      1 |       1 | VALUE 1-1 | Details 1 | Details 2 |
    |      1 |       2 | VALUE 1-2 | Details 1 | Details 2 |
    
  2. from https://stackoverflow.com/questions/21320447/pivot-dynamically-returned-results-from-join-of-two-tables by cc-by-sa and MIT license