2011-12-19 2 views
1

나는 이것을하기 위해 피봇이 필요하다고 확신하지만 그것을 이해할 수는 없다. (SQL의 newb)각 연도의 레코드를 열로 표시하는 피벗 테이블을 작성하려면 어떻게해야합니까?

나는이 같은 데이터를 가지고 :

ID CompanyID Year Revenue Expenses 
1  0003   2011 12000  4000 
2  0003   2010 9000  6000 
3  0003   2009 7000  9000 
4  0010   2011 134300  34000 
5  0010   2010 43000  46000 
6  0010   2009 73000  39000 

나는 이런 식으로이 테이블을 표시하는 피벗을 사용할 수 :

여기
CompanyID 2011-Revenue 2010-Revenue 2009-Revenue 2011-Expenses 2010-Expenses 2009-Expenses 
0003   12000   9000   7000   4000   6000    9000 
0010   134300   43000   73000   34000   46000   39000 

내가 지금까지 무엇을 가지고 ...

SELECT P1.* 
FROM (SELECT [CompanyID] 
      ,CASE P.[Year] WHEN 2011 THEN P.[Revenue] ELSE NULL END AS '2011-Revenue' 
      ,CASE P.[Year] WHEN 2010 THEN P.[Revenue] ELSE NULL END AS '2010-Revenue' 
    FROM tblRecords P WHERE P.[CompanyID] = @companyID GROUP BY CompanyID, [Year], [Revenue]) AS P1 

반환되는 :

두 회사 ID 0003에 대한 기록을 내가 하나 개의 레코드로 그룹에 싶습니다이 인이

  • 나는 단지에서 1 개 회사를 선택할 수 있습니다

    1. 내 결과

      몇몇 문제 ... 시간, 여러 번 선택해야합니다.

    이 어떤 도움을 주시면 감사하겠습니다 .. 그것은 실패하지 않았지만 결과는 헤더와 데이터가없는 단지 빈 테이블이었다 - 나는

    @CompanyIDs 문자열 '0003, 0010'처럼
    FROM tblRecords P 
    WHERE P.[CompanyID] IN (@CompanyIDs) 
    GROUP BY CompanyID, [Year], [Revenue]) AS P1 
    

    시도 .. 내가 피벗을 오해하고 있는지 알려주시겠습니까?

    고맙습니다.

    토마스

    편집 : 마이크로 소프트 SQL Server 관리 Studio 2005 Express를 사용

    업데이트 2 : 나는 그러나 나는 아직도하여 CompanyIDs로 전달 할 수 있어야합니다 자세한 내용은 테이블 조인을 알아 냈어요 쉼표로 구분 된 문자열 .. 어떤 도움을 주시면 감사하겠습니다.

    vvvvvvvv은 내가 (한 번 모두가 노력하고 게시 할 예정입니다)이 아래에 생각

    UPDATE를 vvvvvvv했습니다 루벤 제안했다 내가 조금 더 많은 기능을 필요로하지만 난 그냥 결정했습니다 일 것입니다처럼 보이는 이에...나는 헤더

    이 다른 테이블이 가입 할 수
    CompanyID CompanyName CompanyAddress 2011-Revenue 2010-Revenue 
    
    회사 명 및 다른 테이블에서 온 CompanyAddress (tblCompanyDetails가)

    내가 사용하려고했습니다

    :

    SELECT * 
    FROM 
    (
        SELECT CompanyID, tblCompanyDetails.CompanyName, tblCompanyDetails.CompanyAddress, CAST(YEAR AS varchar) + ' - Revenue' Type, 
          Revenue Value FROM tblRecords 
        FROM tblRecords INNER JOIN tblCompanyDetails ON tblRecords.CompanyID = tblCompanyDetails.CompanyID 
        UNION ALL 
        SELECT CompanyID, tblCompanyDetails.CompanyName, tblCompanyDetails.CompanyAddress, CAST(YEAR AS varchar) + ' - Expenses' Type, 
          Expenses Value FROM tblRecords 
        FROM tblRecords INNER JOIN tblCompanyDetails ON tblRecords.CompanyID = tblCompanyDetails.CompanyID 
    ) src 
        PIVOT 
    (
        SUM(Value) for [Type] in 
    ([2011 - Revenue], [2010 - Revenue], [2009 - Revenue], 
        [2011 - Expenses], [2010 - Expenses], [2009 - Expenses] 
    ) 
    ) pvt 
    WHERE CompanyID = @CompanyID 
    

    나는 오류 :

    Msg 1038, Level 15, State 4, Procedure spCompare, Line 10 
    An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name. 
    
  • +0

    microsoft sql server를 사용 하시겠습니까? –

    +0

    예. 죄송합니다. TSQL 태그가 포함되었지만 더 구체적 일 수 있습니다. Micorsoft SQL Server 2005 – tsdexter

    +0

    일반적으로 서버에서 GROUP BY 만 수행 한 다음 클라이언트 응용 프로그램에서 결과를 크로스 탭하는 것이 더 유연하다고 생각합니다. –

    답변

    2

    시험해보십시오.

    DECLARE @CompanyIDs XML 
    DECLARE @Records TABLE 
    (
        ID int, 
        CompanyID char(4), 
        Year int, 
        Revenue decimal, 
        Expenses decimal 
    ) 
    DECLARE @CompanyDetails TABLE 
    (
        CompanyID char(4), 
        Name varchar(50), 
        Address varchar(50) 
    ) 
    
    SET @CompanyIDs = ' 
    <filter> 
        <CompanyID>0003</CompanyID> 
        <CompanyID>0010</CompanyID> 
    </filter>' 
    
    INSERT INTO @Records 
    (ID, CompanyID, Year, Revenue, Expenses)VALUES 
    (1, '0003', 2011, 12000 , 4000), 
    (2, '0003', 2010, 9000 , 6000), 
    (3, '0003', 2009, 7000 , 9000), 
    (4, '0010', 2011, 134300, 34000), 
    (5, '0010', 2010, 43000 , 46000), 
    (6, '0010', 2009, 73000 , 39000) 
    
    INSERT INTO @CompanyDetails 
    (CompanyID, Name, Address) VALUES 
    ('0003', 'Company A', 'A Street'), 
    ('0010', 'Company B', 'B Street') 
    
    SELECT * 
    FROM 
    (
        SELECT CompanyID, CAST(YEAR AS varchar) + ' - Revenue' Type, 
          Revenue Value FROM @Records 
        UNION ALL 
        SELECT CompanyID, CAST(YEAR AS varchar) + ' - Expenses' Type, 
          Expenses Value FROM @Records 
    ) src 
    PIVOT 
    (
        SUM(Value) for [Type] in 
        ([2011 - Revenue], [2010 - Revenue], [2009 - Revenue], 
        [2011 - Expenses], [2010 - Expenses], [2009 - Expenses] 
        ) 
    ) pvt 
    JOIN @CompanyDetails Details 
        ON Details.CompanyId = pvt.CompanyID 
    WHERE pvt.CompanyID IN 
    (
        SELECT T.C.value('.', 'char(4)') 
        FROM @CompanyIDs.nodes('/filter/CompanyID') T(C) 
    ) 
    

    XML로 회사 필터를 보내고 해당 subselect를 사용하여 피벗 조작에 필요한대로 데이터를 분리해야합니다. JOIN 작업의 경우 pvt 출력

    +0

    그러나이 작업을하는 것처럼 보입니다. CompanyID = @CompanyID를 맨 마지막에 추가 했으므로 모든 연간 데이터가있는 행이 하나 있었지만 CompanyID IN (@CompanyIDs)를 추가했을 때 오류가 발생했지만 방금 빈 테이블을 반환했습니다. where 절을 작동시키는 방법을 알고 있습니까? 이걸 멀리 주셔서 감사합니다. – tsdexter

    +1

    업데이트 해 주셔서 감사합니다. XML로 시도해 보겠습니다. 정말 도움을 주시면 감사하겠습니다. 약간의 업데이트를 참조하십시오. 초기 질문에 빠졌습니다 ... 정말 고마워요. – tsdexter