【问题标题】:sql server - transforming data with dynamic pivot [duplicate]sql server - 使用动态数据转换数据[重复]
【发布时间】:2015-09-05 16:16:11
【问题描述】:

我需要从这种格式动态转换表#table中的数据:

spot_id 名称 pct -------- ---- --- 1 一个 2 1 乙 8 1 C 6 2 一个 4 2 乙 5 3 一个 5 3 天 1 3 E 4

到:

spot_id A B C D E ------- --- --- --- --- --- 1 2 5 6 0 0 2 4 5 0 0 0 3 5 0 0 1 4

问题是我事先不知道“name”列的值是什么或有多少,所以我认为我必须使用某种动态 SQL 旋转


刚刚想出了解决问题的方法:

将@cols 声明为 NVARCHAR(MAX), @query AS NVARCHAR(MAX) 选择 @cols = STUFF((SELECT ',' + QUOTENAME(name) from (SELECT DISTINCT name FROM #table) T FOR XML PATH(''), 类型 ).value('.', 'NVARCHAR(MAX)') ,1,1,'') 设置 @query = N'SELECT spot_id,' + @cols + N' 从 ( 选择 spot_id、名称、pct 来自#table ) 作为 x 枢 ( 最大值(百分比) 对于 (' + @cols + N') 中的名称 ) 作为 p ' exec sp_executesql @query;

如果有更优雅的方式来做同样的事情?

【问题讨论】:

    标签: sql-server tsql pivot dynamic-sql


    【解决方案1】:
    declare @t table (Spot int,name varchar(1),pct int)
    insert into @t(Spot,name,pct)values(1,'A',2),(1,'B',8),(1,'C',6),(2,'A',4),(2,'B',5),(3,'A',5),(3,'D',1),(3,'E',4)
    
    
    select Spot,ISNULL([A],0)[A],ISNULL([B],0)[B],ISNULL([C],0)[C],ISNULL([D],0)[D],ISNULL([E],0)[E] from (Select Spot,PCT,Name from @t)T
    PIVOT(MAX(PCT) FOR Name IN ([A],[B],[C],[D],[E]))P
    
    
    select Spot,ISNULL(MAX(CASE WHEN name = 'A' THEN pct END),0)A,ISNULL(MAX(CASE WHEN name = 'B' THEN pct END),0)B ,
    ISNULL(MAX(CASE WHEN name = 'C' THEN pct END),0)C ,
    ISNULL(MAX(CASE WHEN name = 'D' THEN pct END),0)D ,ISNULL(MAX(CASE WHEN name = 'E' THEN pct END),0)E  from @t
    GROUP BY Spot
    

    使用动态查询:

    if object_id('tempdb..#t') is not null
        drop table #t
    
    CREATE  table #t(Spot int,name varchar(1),pct int)
    insert into #t(Spot,name,pct)values(1,'A',2),(1,'B',8),(1,'C',6),(2,'A',4),(2,'B',5),(3,'A',5),(3,'D',1),(3,'E',4)
    
    DECLARE @statement NVARCHAR(max)
    ,@columns NVARCHAR(max)
    
    SELECT @columns = ISNULL(@columns + ', ', '') + N'[' + tbl.name + ']'
    FROM (
       SELECT DISTINCT name
       FROM #t
       ) AS tbl
    
    SELECT @statement = ' select Spot,ISNULL([A],0)[A],ISNULL([B],0)[B],ISNULL([C],0)[C],ISNULL([D],0)[D],ISNULL([E],0)[E] from (Select Spot,PCT,Name from #t)T
    PIVOT(MAX(PCT) FOR Name IN (' + @columns + ')) as pvt'
    
    EXEC sp_executesql @statement = @statement
    

    【讨论】:

    • 谢谢,但这对我帮助不大,因为就像我写的那样,“名称”列(A、B、C、D)的值是动态的,我不知道它们是什么.它必须以某种方式是动态的
    • 仍然对我没有多大帮助..“名称”列的值是动态的..我只是想出了答案。我会在我的问题中发布它
    • 请用动态查询@user2822455查看更新后的答案
    • 那个更好。 @statement 仍然不是动态的 - 请参阅我的答案..并感谢您的帮助:)
    • 欢迎,只要您的问题解决了,我给了您三种方法来实现表格格式(使用最大案例、正常枢轴和动态)@user2822455
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 2019-12-05
    • 2014-03-11
    相关资源
    最近更新 更多