【问题标题】:Swap Some Rows into Columns in SQL Server 2008在 SQL Server 2008 中将一些行交换为列
【发布时间】:2012-03-04 01:15:41
【问题描述】:

另一位 SQL Server 专家为您服务...

我有一张这样的桌子......

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

Action 列可能有许多不同类型的状态,这些状态不一定是固定的。

我需要输出如下:

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

如何做到这一点?救命!

【问题讨论】:

  • 我已经设法获得了带有 AccountManager、Action、Count 列的原始表,但我唯一能想到的要获得我需要的表,就是用我想要的游标来做到这一点避免。
  • 为什么这个问题被否决???

标签: sql sql-server sql-server-2008 tsql


【解决方案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,
    '+@colsWithIsNull+'
FROM
(
SELECT
    tbl.AccountManager,
    tbl.Action,
    tbl.Count
FROM
    #tbl AS tbl
) AS p
PIVOT
(
    SUM([Count])
    FOR [Action] IN('+@cols+')
) AS pvt'

EXECUTE(@query)

然后在我的情况下,我将删除临时表:

DROP TABLE #tbl

【讨论】:

  • 行中动态数据的绝佳答案!
【解决方案2】:
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

【讨论】:

    【解决方案3】:

    【讨论】:

    • 非常感谢 - 我会试试这个
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多