1

我已经搜索并找不到完全符合我需求的解决方案,也找不到我可以修改的解决方案。我有一个数据库表,为简单起见,我们会说它有三列(packageIDcarriersequence)。对于任何包裹,都可能有一个或多个承运人处理该包裹。我可以做一个查询

SELECT packageID, carrier 
FROM packageFlow 
ORDER BY sequence

获取所有处理过包裹的人的列表,如下所示:

packageID, carrier
1, Bob
1, Jim
1, Sally
1, Ron
2, Reggie
2, Mary
2, Bruce

我需要的是将结果放入如下所示的行中:

packageID|carrier1|carrier2|carrier3|carrier4
   1     |Bob     |Jim     |Sally   |Ron
   2     |Reggie  |Mary    |Bruce

Pivot 似乎没有做我需要的事情,因为我没有聚合任何东西,我也无法让 CTE 正常工作。我会很感激任何朝着正确方向的推动。

4

1 回答 1

3

此数据转换是一个PIVOT. 从 SQL Server 2005 开始,有一个函数可以将行转换为列。

如果您有已知数量的值,则可以对查询进行硬编码:

select *
from 
(
  select packageid, carrier,
    'Carrier_'+cast(row_number() over(partition by packageid order by packageid) as varchar(10)) col
  from packageflow
) src
pivot
(
  max(carrier)
  for col in (Carrier_1, Carrier_2, Carrier_3, Carrier_4)
) piv

请参阅SQL Fiddle with Demo

如果您想将未知数量的Carrier值转换为列,则可以使用动态 sql:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(t.col) 
                    from 
                    (
                      select 'Carrier_'+cast(row_number() over(partition by packageid order by packageid) as varchar(10)) col
                      from packageFlow
                    ) t                    
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT packageid,' + @cols + ' from 
             (
                select packageid, carrier,
                  ''Carrier_''+cast(row_number() over(partition by packageid order by packageid) as varchar(10)) col
                from packageflow
            ) x
            pivot 
            (
                max(carrier)
                for col in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo

注意:您将替换order by packageidorder by sequence

两个查询的结果是:

| PACKAGEID | CARRIER_1 | CARRIER_2 | CARRIER_3 | CARRIER_4 |
-------------------------------------------------------------
|         1 |       Bob |       Jim |     Sally |       Ron |
|         2 |    Reggie |      Mary |     Bruce |    (null) |
于 2013-03-01T17:06:25.350 回答