SQL将行转置为列(按键变量分组)不使用pivot

时间:2015-04-16 16:19:39

标签: sql-server tsql pivot transpose

以下代码接近于我需要做的事情除了我应该动态生成列(p1,p2,p3 ...)而且我不能使用pivot(参见SQL Transpose rows to columns (group by key variable))。

我现在在SQL Server 2008中使用的是什么:

Select InvoiceNum, 
Max(Case when seq =0  Then product_Description end) as p1,
Max(Case when seq =1 Then product_Description end) as p2

 From  

( Select InvoiceNum, Product_Description,

    Row_Number() Over(Partition by InvoiceNum
        Order by InvoiceNum) - 1 seq

From #tmpTable
)d
 Group by InvoiceNum

谢谢StackOverFlow社区!!

1 个答案:

答案 0 :(得分:1)

我认为,就像评论中所说的那样,您应该将动态SQL与PIVOT表一起使用。它可能比这更有效率。

创建表并在其中放入一些数据:

create table invoiceTable (
    InvoiceNum int,
    Product_Description nvarchar(20)
)

insert into invoiceTable values (1, 'inv1 row 1'),(1, 'inv1 row 2'),(1, 'inv1 row 3'),(2, 'inv2 row 1'),(2, 'inv2 row 2')

声明必要的变量

declare @maxNo int
declare @query nvarchar(max)
declare @i int = 0

找到最大行号:

select @maxNo = max(seq) from 
    (
    Select 
         InvoiceNum
        ,Product_Description
        ,Row_Number() Over(Partition by InvoiceNum Order by InvoiceNum) - 1 seq
    From 
        invoiceTable
    ) maxRowNo

构建动态查询

set @query = 
'
Select 
    *
From  
( 
    Select 
         InvoiceNum
        ,Product_Description
        ,Row_Number() Over(Partition by InvoiceNum Order by InvoiceNum) - 1 seq
    From 
        invoiceTable
) d
pivot
(
    min(Product_Description)
    for seq in (
    '

while (@i <= @maxNo)
begin
    if (@i > 0) set @Query += ','
    set @query += '['+CAST(@i as nvarchar)+']'

    set @i += 1;
end

set @query +=
    ')
) pvt
'

执行查询

exec sp_executesql @query

这给出了以下结果集:

InvoiceNum  0           1           2
1           inv1 row 1  inv1 row 2  inv1 row 3
2           inv2 row 1  inv2 row 2  NULL