我已经搜索过,无法找到完全符合我需求的解决方案,也找不到我可以修改的解决方案。我有一个数据库表,为简单起见,我们会说它有三列(packageID
,carrier
和sequence
)。对于任何包装,可以有一个或多个处理包装的承运人。我可以像
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正常工作。我很欣赏任何朝着正确方向的推动。
答案 0 :(得分: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
如果您要将未知数量的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)
注意:您将order by packageid
替换为order by sequence
两个查询的结果是:
| PACKAGEID | CARRIER_1 | CARRIER_2 | CARRIER_3 | CARRIER_4 |
-------------------------------------------------------------
| 1 | Bob | Jim | Sally | Ron |
| 2 | Reggie | Mary | Bruce | (null) |