2

早上好,

我有 2 个视图: ICCUDays,每个账户包含一条记录,字段 ACCOUNT 和 ICCUDays,ICCUEnctrSelectedRevCatsDirCost,每个账户包含多个记录,字段 ACCOUNT、UBCATEGORY 和 DirectCost。

我的目标:创建一个存储过程,通过 UBCATEGORY 使用 ICCUDays 和 DirectCost 为每个 ACCOUNT 输出一条记录。这将是一个交叉表或数据透视表,并且必须允许在一个或多个直接成本子类别桶中出现空值的可能性。最后,需要将此交叉表或数据透视表发送到新表 EnctrUBCatPivot。

问题:上述场景的正确 PIVOT 语法是什么?鉴于我想为许多 UBCATEGORY 条目输出直接成本,我如何编写 TSQL 来迭代这些并按帐户和 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

这很好用,因为它为每个 UBCATEGORY 输出帐户和所有直接成本。但是,我需要在 ACCOUNT 上内部加入 vwICCUDAYS 以向 ICCUDays 的数据透视表添加一列。每个 UBCATEGORYmid 的最终数据透视列应该是 Account、ICCUDays、Direct Cost。

我对合并语法不是很熟悉,因此无法辨别如何修改它以添加更多列,我也不确定如何/在何处添加内部连接语法以添加 ICCUDays。

有人可以指出我正确的方向吗?谢谢, 席德

4

1 回答 1

4

You need to know all of the possible values to PIVOT by. So it is difficult to do this with T-SQL directly unless you use dynamic SQL and this can get hairy pretty quickly. Probably better to pass all of the rows back to the presentation tier or report writer and let it turn them sideways.

Here is a quick PIVOT example if you know all of the UBCategory values in advance. I left out ICCUDays since it seems rather irrelevant unless there are columns that come from that view as part of the result.

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;

To make this more dynamic, you'd have to get the comma separated list of DISTINCT UBCategory values, and build the pivot on the fly. So it might look like this:

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;

Then to "send the data to a new table" you can just make the query an INSERT INTO ... SELECT instead of a straight SELECT. Of course, this seems kind of useless, because in order to write that insert statement, you need to know the order of the columns (which isn't guaranteed with this approach) and you need to have already put in columns for each potential UBCategory value anyway, so this seems very chicken and egg.

于 2010-02-05T19:41:07.307 回答