2012-03-03 80 views
0

另外一个为你的SQL Server大师......交换一些行转换成列在SQL Server 2008

我有一个表是这样的...

AccountManager | Action    | Count 
----------------------------------------------------- 
Joe   | Client Negotiation | 10 
Bloggs   | Closing    | 1 
Aunty   | Email     | 12 
Marie   | Preparing Contract | 32 

的动作栏可以有许多不同类型的可能不一定是固定的状态。

我需要的输出为以下几点:

AccountManager | Client Negotiation | Closing | Email | Preparing Contract 
-------------------------------------------------------------------------- 
Joe   | 10     | 0  | 0  | 0 
Bloggs   | 0     | 1  | 0  | 0 
Aunty   | 0     | 0  | 12 | 0 
Marie   | 0     | 0  | 0  | 32 

这怎么可能实现?帮帮我!

+0

[你有什么尝试?](http://mattgemmell.com/2008/12/08/what-have-you-tried/) – 2012-03-03 16:04:58

+0

我已经设法使用AccountManager获得原始表格, Action,Count列,但我能想到的唯一能够获得我需要的表的方法是使用游标执行此操作,这是我想要避免的。 – AshesToAshes 2012-03-03 16:06:07

+0

为什么这个问题被否决? – AshesToAshes 2012-03-03 16:10:06

回答

0

这最好由您正在使用的报告工具处理。寻找“数据透视表”。

+0

什么报告工具?我在纯SQL中做这件事...... – AshesToAshes 2012-03-03 16:07:08

1
select [AccountManager], ISNULL([Email],0) as [Email], ISNULL([Closing],0) as [Closing], ISNULL([Preparing Contact],0) as [Preparing Contact], ISNULL([Client Negotiation],0) as [Client Negotiation] from 
    (SELECT * FROM TestPivot) as SourceTable 

Pivot 
(
    SUM([Count]) 
    For [Action] in ([Email], [Closing], [Preparing Contact], [Client Negotiation]) 
) as PivotedColumns 
order by [Email] desc, [Closing] desc, [Preparing Contact] desc, [Client Negotiation] desc 
1

也许是这样的:

首先,测试数据:

CREATE TABLE #tbl (AccountManager VARCHAR(100), Action VARCHAR(100),Count INT) 

INSERT INTO #tbl 
VALUES 
    ('Joe','Client Negotiation',10), 
    ('Bloggs','Closing',1), 
    ('Aunty','Email',12), 
    ('Marie','Preparing Contract',32) 

如果您知道列是静态的。然后,你可以这样做:

SELECT 
    AccountManager, 
    ISNULL([Client Negotiation],0) AS [Client Negotiation], 
    ISNULL([Closing],0) AS [Closing], 
    ISNULL([Email],0) AS [Email], 
    ISNULL([Preparing Contract],0) AS [Preparing Contract] 
FROM 
(
SELECT 
    tbl.AccountManager, 
    tbl.Action, 
    tbl.Count 
FROM 
    #tbl AS tbl 
) AS p 
PIVOT 
(
    SUM([Count]) 
    FOR [Action] IN([Client Negotiation],[Closing],[Email],[Preparing Contract]) 
) AS pvt 

否则,你必须做一个动态的支点是这样的:

首先,独特的列名:

DECLARE @cols VARCHAR(MAX), 
     @colsWithIsNull VARCHAR(MAX) 
;WITH CTE 
AS 
(
    SELECT 
     ROW_Number() OVER(PARTITION BY tbl.Action ORDER BY tbl.Action) AS iRank, 
     tbl.Action 
    FROM 
     #tbl AS tbl 
) 
SELECT @cols = COALESCE(@cols + ','+QUOTENAME(Action), 
        QUOTENAME(Action)), 
     @colsWithIsNull=COALESCE(@colsWithIsNull + ',ISNULL('+QUOTENAME(Action)+',0) AS '+QUOTENAME(Action), 
        'ISNULL('+QUOTENAME(Action)+',0) AS '+QUOTENAME(Action)) 
FROM 
    CTE 
WHERE 
    iRank=1 

然后动态支点是这样的:

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    AccountManager, 
    '[email protected]+' 
FROM 
(
SELECT 
    tbl.AccountManager, 
    tbl.Action, 
    tbl.Count 
FROM 
    #tbl AS tbl 
) AS p 
PIVOT 
(
    SUM([Count]) 
    FOR [Action] IN('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

然后在我的情况下,我会放下临时表:

DROP TABLE #tbl 
+0

行中动态数据的绝佳答案! – AshesToAshes 2012-03-03 20:57:40

+0

谢谢。乐意效劳 :-) – Arion 2012-03-03 21:12:00