2010-02-05 4 views
2

좋은 아침,는 어떻게이 전망이 두보기

가입 저장 프로 시저 SQL Server 2005에서 PIVOT을 사용하는 계정, UBCATEGORY 및 DirectCost.

내 목표 : UBCATEGORY에 의해 ICCUDays 및 DirectCost가있는 계정 당 하나의 레코드를 출력하는 저장 프로 시저를 만듭니다. 이는 크로스 탭 또는 피벗 일 것이며 하나 이상의 직접 비용 ubcategory bucket에서 null 가능성을 허용해야합니다. 마지막으로이 크로스 탭 또는 피벗을 새 테이블 EnctrUBCatPivot에 보내야합니다.

질문 : 위의 시나리오에서 올바른 PIVOT 구문은 무엇입니까? 많은 UBCATEGORY 항목에 대한 직접 비용을 감안할 때 TSQL을 반복 작성하고 계정 및 UBCATEGORY별로 피벗 (pivot)을 수행하려면 어떻게해야합니까? 이 모든 것이 하나의 sproc에서 성취 되었습니까? 아니면 결과를 테이블에 쓰려면 여러 sprocs로 분리되어야합니까? 이 계정 및 각 UBCATEGORY에 대한 모든 직접 비용을 출력한다는 점에서

ALTER PROCEDURE [dbo].[spICCUMain] 
-- Add the parameters for the stored procedure here 

AS 
declare @columns varchar(8000) 

BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
SELECT @columns = COALESCE(@columns + ',[' + cast(UBCATEGORYmid as varchar) + ']','[' + cast(UBCATEGORYmid as varchar)+ ']') 
FROM vwICCUEnctrSelectedRevCatsDirCost 
GROUP BY UBCATEGORYmid 


DECLARE @query VARCHAR(8000) 

SET @query = ' 
SELECT * 
FROM vwICCUEnctrSelectedRevCatsDirCost 
PIVOT 
(
MAX(DirectCost) 
FOR [UBCATEGORYmid] 
IN (' + @columns + ') 
) 
AS p' 

EXECUTE(@query) 

END 

이 잘 작동 :

는 여기에 지금까지 작성한 코드입니다. 그러나 ICCUDays의 피벗에 열을 추가하려면 ACCOUNT의 vwICCUDAYS에 내부 조인을해야합니다. 최종 피벗 열은 계정, ICCUDays, 각 UBCATEGORYmid의 직접 비용이어야합니다.

필자는 병합 구문에 익숙하지 않아 추가 열을 추가하기 위해이를 수정하는 방법을 식별 할 수 없으며 ICCUDays를 추가하기 위해 내부 조인 구문을 추가하는 방법이나 위치가 확실하지 않습니다.

누군가 적절한 방향으로 나를 가리킬 수 있습니까? 감사합니다. 시드

+0

뷰를 쿼리의 기초로 사용하는 특별한 이유가 있습니까? –

답변

4

PIVOT을 사용하여 가능한 모든 값을 알아야합니다. 따라서 동적 SQL을 사용하지 않는 한 T-SQL을 사용하여이 작업을 수행하는 것이 어렵습니다. 모든 행을 프리젠 테이션 계층이나 보고서 작성자에게 다시 전달하여 옆으로 돌려 놓는 것이 좋습니다.

미리 UBCategory 값을 모두 알고있는 경우 빠른 PIVOT 예입니다. 결과의 일부로 해당보기에서 오는 열이 없으면 오히려 중요하지 않으므로 ICCUDays를 생략했습니다.

USE tempdb; 
GO 
SET NOCOUNT ON; 
GO 

-- who on earth is responsible for your naming scheme? 
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost 
(
    Account INT, 
    UBCategory VARCHAR(10), 
    DirectCost DECIMAL(9,2) 
); 

INSERT dbo.ICCUEnctrSelectedRevCatsDirCost 
    SELECT 1, 'foo', 5.25 
    UNION SELECT 1, 'bar', 6.25 
    UNION SELECT 1, 'smudge', 8.50 
    UNION SELECT 2, 'foo', 9.25 
    UNION SELECT 2, 'brap', 2.75; 

SELECT Account,[foo],[bar],[smudge],[brap] FROM 
    dbo.ICCUEnctrSelectedRevCatsDirCost 
    -- WHERE <something>, I assume ??? 
PIVOT 
(
    MAX(DirectCost) 
    FOR UBCategory IN ([foo],[bar],[smudge],[brap]) 
) AS p; 

GO 
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost; 

는 쉼표 DISTINCT UBCategory 값의 목록을 분리 얻을 수있는 것, 이것이 더 역동적 확인하고 즉석에서 피벗을 구축합니다. 그래서 다음과 같습니다
USE tempdb; 
GO 
SET NOCOUNT ON; 
GO 

-- who on earth is responsible for your naming scheme? 
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost 
(
    Account INT, 
    UBCategory VARCHAR(10), 
    DirectCost DECIMAL(9,2) 
); 

INSERT dbo.ICCUEnctrSelectedRevCatsDirCost 
    SELECT 1, 'foo', 5.25 
    UNION SELECT 1, 'bar', 6.25 
    UNION SELECT 1, 'smudge', 8.50 
    UNION SELECT 2, 'foo', 9.25 
    UNION SELECT 2, 'brap', 2.75 
    UNION SELECT 3, 'bingo', 4.00; 

DECLARE @sql NVARCHAR(MAX), 
    @col NVARCHAR(MAX); 

SELECT @col = COALESCE(@col, '') + QUOTENAME(UBCategory) + ',' 
    FROM 
    (
     SELECT DISTINCT UBCategory 
     FROM dbo.ICCUEnctrSelectedRevCatsDirCost 
    ) AS x; 

SET @col = LEFT(@col, LEN(@col)-1); 

SET @sql = N'SELECT Account, $col$ FROM 
    dbo.ICCUEnctrSelectedRevCatsDirCost 
    -- WHERE <something>, I assume ??? 
PIVOT 
(
    MAX(DirectCost) 
    FOR UBCategory IN ($col$) 
) AS p;'; 

SET @sql = REPLACE(@sql, '$col$', @col); 

--EXEC sp_executeSQL @sql; 
PRINT @sql; 

GO 
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost; 

그런 다음 "새 테이블에 데이터를 보내기"당신은 대신 직선 SELECT의 SELECT ... 쿼리는 INSERT INTO를 만들 수 있습니다. 물론 이것은 삽입 문을 작성하기 위해 열의 순서 (이 접근법으로 보장되지 않음)를 알아야하고 각 잠재적 UBCategory에 대해 열을 이미 입력해야하기 때문에 유용하지 않습니다. 값 어쨌든, 이것은 매우 닭고기와 계란 것 같습니다.

+0

SSRS 2005에 그룹화, 피벗 팅 (pivoting) 등을시키는 것이 좋습니다. Dynamic TSQL을 사용하는 것보다 권장 할만한 이유는 무엇입니까? 나에게 명확히 해 주셔서 감사합니다 :) – SidC

+0

글쎄, 결과 세트의 모양을 모르는 경우 데이터를 다른 테이블로 "보내"는 것을 잘 모르겠다.동적 SQL을 사용하여 검색해야하는 UBCategory가있는 경우 대상 테이블에 이미 해당 열이 정의되어있는 것이 어떨까요? 프런트 엔드는 이러한 종류의 디스플레이를 다루는면에서보다 융통성이 있습니다. 동적 SQL 찬반론에 대한 좋은 입문서는 http://www.sommarskog.se/dynamic_sql.html을 참조하십시오. –

+0

당신의 도움에 감사드립니다 !! – SidC