2009-06-03 3 views
14

필자는 열을 피벗 할 필요가있는 여러 행이있는 테이블로 작업하고 있습니다. 피벗은이를위한 완벽한 솔루션이며 필요한 모든 것이 하나의 필드 일 때 잘 작동합니다. 피벗을 기반으로 여러 필드를 반환해야합니다. 여기에 구체적인와 의사 코드는 밖으로 제거된다T-SQL의 다중 열 피벗

SELECT 
    field1, 
    [1], [2], [3], [4] 
FROM 
    (
    SELECT 
    field1, 
    field2, 
    (ROW_NUMBER() OVER(PARTITION BY field1 ORDER BY field2)) RowID 
    FROM tblname 
) AS SourceTable 
PIVOT 
    (
    MAX(field2) 
    FOR RowID IN ([1], [2], [3], [4]) 
) AS PivotTable; 

위의 구문은 훌륭하게 작동하지만 추가 정보는 FIELD3, 입력란 4에서 발견하는 데 필요한 때 무엇을해야합니까 ...?

+2

정확히 무엇이 필요합니까? –

+0

잘 해내려고 노력했습니다 (블로그의 3 번째 접근 방식). http://dba.stackexchange.com/questions/65786/query-pivot-multiple-columns-variable-number-ofrows – JayaPrakash

답변

11

MAX를 사용하여 재 작성 (CASE ...)와 GROUP :

select 
    field1 
, [1] = max(case when RowID = 1 then field2 end) 
, [2] = max(case when RowID = 2 then field2 end) 
, [3] = max(case when RowID = 3 then field2 end) 
, [4] = max(case when RowID = 4 then field2 end) 
from (
    select 
    field1 
    , field2 
    , RowID = row_number() over (partition by field1 order by field2) 
    from tblname 
) SourceTable 
group by 
    field1 

은 거기에서

+0

내가 결론을 내린 것은 CTE에서 CASe 문을 사용하여이 파생 테이블을 채우는 것이 었습니다.이 파생 테이블을 추가 기준으로 결합했습니다. ----------------------- – websch01ar

+0

cteSec와 마찬가지로 ( \t는 \t vSec.ID을 선택 \t --Secretary 1 다음의 CTE이고 - \t MAX ( \t \t 경우 vSec.RowID \t \t 1 THEN vSec.field1 ELSE \t \t ' \t \t \t END) SEC_OfficePhone1, \t MAX (\t \t 사례 vSec.RowID \t \t WHEN 1 THEN vSec.ELSE FIELD2 \t \t ' \t \t END \t) SEC_OfficeFax1, \t FROM \t \t \t 선택 TOP 100 PERCENT \t ( \t --This 내측 QUERY를 (그것이 총무 행에 할당 될 것이다) \t 필드 1, 2 필드, ID (vs.ID ORDER BY vs.ID2 BY ROW_NUMBER() OVER (파티션))대 tblname FROM \t \t \t을 ROWID vs.ID BY 0 \t ORDER, ID2 \t) \t vSec.ID ) – websch01ar

+0

BY vSec \t GROUP 그래서이 방법을 통해 내가 기대하고 열 수를 하드 코딩했다. 나는 일반적으로 바꿀 수있는 바대로이 작업을 동적으로 수행하는 것을 선호합니다. 그러나 회사로서, 우리는 간접비 절감에 초점을 맞추고 있습니다. 그래서 보스 당 4 명 이상의 비서가 필요하지 않습니다. 귀하의 게시물은 20 개의 사례를 작성하는 길로 이끌었 기 때문에 저는 신용을 제공합니다 진술. 이것은 1 초 미만의 응답으로 매력처럼 작동합니다. – websch01ar

1

MS SQL Server를 사용하고 있는지 확신 할 수 없지만 사용자가 ... 엔진의 CROSS APPLY 기능을 살펴볼 수 있습니다. 기본적으로 테이블 반환 UDF의 결과를 결과 집합에 적용 할 수 있습니다. 이렇게하려면 피벗 쿼리를 테이블 반환 결과 집합에 넣어야합니다. BY

http://weblogs.sqlteam.com/jeffs/archive/2007/10/18/sql-server-cross-apply.aspx

+0

-1 질문과의 관계를 볼 수 없습니다 – Andomar

+0

질문은 T-SQL . 그것은 MS 사투리입니다. – RolandTumble

+0

또한 Sybase의 dialect입니다. –

1

등 FIELD3, 입력란 4에 추가로 SQL 문을 래핑 할 수 다음과 같이 입력하십시오 :

결과를 하나의 행으로 축소해야합니다. field1에 그룹화.

1

ROW_NUMBER를 통해 여러 피벗을 수행하는 트릭은 순서와 필드 번호를 모두 저장하기 위해 해당 행 번호 순서를 수정하는 것입니다. 다음은 여러 PIVOT 문으로 원하는 것을 수행하는 예제입니다.

-- populate some test data 
if object_id('tempdb..#tmp') is not null drop table #tmp 
create table #tmp (
    ID int identity(1,1) not null, 
    MainField varchar(100), 
    ThatField int, 
    ThatOtherField datetime 
) 

insert into #tmp (MainField, ThatField, ThatOtherField) 
select 'A', 10, '1/1/2000' union all 
select 'A', 20, '2/1/2000' union all 
select 'A', 30, '3/1/2000' union all 
select 'B', 10, '1/1/2001' union all 
select 'B', 20, '2/1/2001' union all 
select 'B', 30, '3/1/2001' union all 
select 'B', 40, '4/1/2001' union all 
select 'C', 10, '1/1/2002' union all 
select 'D', 10, '1/1/2000' union all 
select 'D', 20, '2/1/2000' --union all 

-- pivot over multiple columns using the 1.1, 1.2, 2.1, 2.2 sequence trick 
select 
    MainField, 
    max([1.1]) as ThatField1, 
    max([1.2]) as ThatOtherField1, 
    max([2.1]) as ThatField2, 
    max([2.2]) as ThatOtherField2, 
    max([3.1]) as ThatField3, 
    max([3.2]) as ThatOtherField3, 
    max([4.1]) as ThatField4, 
    max([4.2]) as ThatOtherField4 
from 
    (
     select x.*, 
      cast(row_number() over (partition by MainField order by ThatField) as varchar(2)) + '.1' as ThatFieldSequence, 
      cast(row_number() over (partition by MainField order by ThatField) as varchar(2)) + '.2' as ThatOtherFieldSequence 
     from #tmp x 
    ) a 
    pivot (
     max(ThatField) for ThatFieldSequence in ([1.1], [2.1], [3.1], [4.1]) 
    ) p1 
    pivot (
     max(ThatOtherField) for ThatOtherFieldSequence in ([1.2], [2.2], [3.2], [4.2]) 
    ) p2 
group by 
    MainField