Row_Number()需要动态数据透视

时间:2015-04-10 20:02:26

标签: sql sql-server pivot row-number dynamic-columns

我正在使用Microsoft SQL Server Management Studio 2008.

我的数据如下:

Client ID        Value
-------------------------------
12345            Did Not Meet
12345            Did Not Meet
12345            Partially Met
12346            Partially Met
12346            Partially Met
12346            Partially Met
12347            Partially Met
12347            Partially Met
12347            Did Not Meet
12347            Met

我希望结果看起来像这样:

Client ID                Value1                Value2                   Value3                      Value4

12345                    Did Not Meet           Did Not Meet            Partially Met                NULL
12346                    Partially Met          Partially Met           Partially Met                NULL
12347                    Partially Met          Partially Met           Did Not Meet                 Met         

列未知,所以我知道我需要动态查询。我尝试了一个带有pivot函数的动态查询,但只在相同类型的值下进行了分组。所以聚合函数对我不利。

这是我试过的查询:

Declare @Columns nvarchar(max); 
Declare @DynamicPivotQuery nvarchar(max);   

Select @Columns=    
COALESCE(@Columns+',','')+QUOTENAME(Value)  
from (select distinct Document.Value
from Document d 
join Client c on d.clientid=c.id    
    )
 as t1  


Set @DynamicPivotQuery= 
 N'Select ClientID, ' + @Columns + '    
 from   
 (select Document.ClientID, 
  DocumentFact.Value,   
   from Document d
   join Client c on d.clientid=c.id 
 ) p    
Pivot (max(Value) for Value in ('+@Columns+'))  
 as pivottable  
 order by ClientID;'

Exec(@DynamicPivotQuery)

接下来我添加了row_number和分区函数,但似乎无法调试它。我得到的错误是:

  

Msg 102,Level 15,State 1,Line 29
  ')'附近的语法不正确。

靠近XML Path函数。

对此有任何帮助将不胜感激。感谢。

select @Columns=    
COALESCE(@Columns+',','')+QUOTENAME(Value)  
from (select distinct Document.Value    
, 'name'+ CAST (row_number() over   
(Partition BY clientid order by clientid) as NVARCHAR (10)) as Cols 
from document d
join Clients c on d.clientid=c.id   

 t1 

 --FOR XML PATH('')),      1, 1, N'');
 FOR XML PATH('')), TYPE).value('.','NVARCHAR(MAX)'),1,2,'')    
  order by ClientID 

1 个答案:

答案 0 :(得分:2)

使用cte,使用row_number即可获得结果:

您的架构:

create table your_table([Client ID] int ,Value varchar(50));
insert into your_table values
(12345,            'Did Not Meet'),
(12345,            'Did Not Meet'),
(12345,            'Partially Met'),
(12346,            'Partially Met'),
(12346,            'Partially Met'),
(12346,            'Partially Met'),
(12347,            'Partially Met'),
(12347,            'Partially Met'),
(12347,            'Did Not Meet'),
(12347,            'Met');

查询:

with cte as
(
 select [Client ID] ci,value,
        row_number() over(partition by [Client ID] order by value) as rn
 from your_table
)
select distinct ci as [Client ID],
       (select ct.value from cte ct where ct.ci=cte.ci and ct.rn=1) value1,
       (select ct.value from cte ct where ct.ci=cte.ci and ct.rn=2) value2,
       (select ct.value from cte ct where ct.ci=cte.ci and ct.rn=3) value3,
       (select ct.value from cte ct where ct.ci=cte.ci and ct.rn=4) value4
from cte

结果:

Client ID   value1          value2          value3          value4
12345       Did Not Meet    Did Not Meet    Partially Met   (null)
12346       Partially Met   Partially Met   Partially Met   (null)
12347       Did Not Meet    Met Partially   Met Partially    Met