数据透视表是否可以使用未知数量的列?

时间:2014-02-17 17:14:30

标签: sql sql-server-2012

如果我有一个包含未知数量成员的团队表,有没有办法让数据透视查询动态化?

    create table #t (
    team varchar (20), member varchar (20)
)
insert into #t values ('ERP', 'Jack')
insert into #t values ('ERP', 'John')
insert into #t values ('ERP', 'Mary')
insert into #t values ('ERP', 'Tim')
insert into #t values ('CRM', 'Robert')
insert into #t values ('CRM', 'Diana')

select * from #t

select team, [1] as teamMember1,    /* 1st select */
    [2] as teamMember2, [3] as teamMember3
 from 
(select team , member, row_number ()    /* 3rd select */
    over (partition by team order by team) as rownum
from #t) a
pivot (max(member) for rownum in ([1], [2], [3])) as pvt

drop table #t

1 个答案:

答案 0 :(得分:0)

为什么是,是的。这是我多年前为一个类似的问题编写的脚本,最终通过给用户Excel并洗手来解决。我很抱歉没有配置您的示例数据,但希望它很容易理解。

希望有所帮助,

约翰

--------------START QUERY--------------
-- Example Table
CREATE TABLE #glbTestTable
(
    ProviderID  INT,
    Total       INT,
    PaymentDate SMALLDATETIME
)

--So the dates insert properly
SET DATEFORMAT dmy

-- Populate Example Table
INSERT INTO #glbTestTable VALUES (232, 12200, '12/01/09') 
INSERT INTO #glbTestTable VALUES (456, 10200, '12/01/09') 
INSERT INTO #glbTestTable VALUES (563, 11899, '02/03/09') 
INSERT INTO #glbTestTable VALUES (221, 5239, '13/04/09') 
INSERT INTO #glbTestTable VALUES (987, 7899, '02/03/09') 
INSERT INTO #glbTestTable VALUES (1, 1234, '02/08/09') 
INSERT INTO #glbTestTable VALUES (2, 4321, '02/07/09') 
INSERT INTO #glbTestTable VALUES (3, 5555, '02/06/09')

-- Raw Output
SELECT *
FROM #glbTestTable

-- Build Query for Pivot --
DECLARE @pvtColumns VARCHAR(MAX)
SET @pvtColumns = ''

-- Grab up to the first 1023 "Columns" that we want to use in Pivot Table.
--  Tables can only have 1024 columns at a maximum
SELECT TOP 1023 @pvtColumns = @pvtColumns + '[' + CONVERT(VARCHAR, PaymentDate, 103) + '], '
FROM (SELECT DISTINCT PaymentDate FROM #glbTestTable) t_distFP

-- Create PivotTable Query
DECLARE @myQuery VARCHAR(MAX)
SET @myQuery = '
SELECT ProviderID, ' + LEFT(@pvtColumns, LEN(@pvtColumns) - 1) + '
FROM (SELECT ProviderID, PaymentDate, Total
    FROM #glbTestTable) AS SourceTable
PIVOT
(
    SUM(Total)
    FOR PaymentDate IN (' + LEFT(@pvtColumns, LEN(@pvtColumns) - 1) + ')
) AS PivotTable'

-- Run the Pivot Query
EXEC(@myQuery)

-- Cleanup
DROP TABLE #glbTestTable
---------------END QUERY---------------