2

我正在尝试在 SQL Server 2008 R2 中加入三个表,我希望将第二个表中的项目添加为新列。

详细解释 - 我有 3 个表:

第一个表包含用户名和用户 ID

UserID UserName
1       Mike
2       John
3       George

第二个表是带有职位名称的职位 ID

PositionID PositionName
1          RW
2          LW
3          DF
4          MDF
5          SS
6          CF
etc

第三个表包含他们的首选位置,其中一个用户可以拥有多个

UserID  PositionId
1        1
1        3
2        2
2        3
2        5
3        2
3        7

当我加入这些表时,我想为每个用户获得单行,其中包含所有首选位置,例如

UserID   UserName  PreferedPosition  PreferedPosition2 PreferedPosition3
1        Mike      RW                LW               
2        John      CMF               SS                CF
3        George    LW                MDF

我不知道如何实现这一点,任何帮助将不胜感激。

4

1 回答 1

2

如果你只有几个职位,你可以用PIVOT关键字来做

select
    UserID,
    UserName,
    [1] as Position1,
    [2] as Position2,
    [3] as Position3
from
(
    select
        U.UserID, U.UserName, P.PositionName,
        row_number() over (partition by U.UserID order by P.PositionName) as RowNum
    from Positions_Users as PU
        inner join Positions as P on P.PositionID = PU.PositionID
        inner join Users as U on U.UserID = PU.UserID
) as P
    pivot
    (
        min(P.PositionName)
        for P.RowNum in ([1], [2], [3])
    ) as PIV

SQL 小提琴

但是,如果您想要动态列数,则必须使用动态 SQL,如下所示

declare @stmt nvarchar(max), @stmt_columns1 nvarchar(max), @stmt_columns2 nvarchar(max)
declare @Temp_Data table (RowNum nvarchar(max))

insert into @Temp_Data
select distinct row_number() over (partition by U.UserID order by P.PositionName) as RowNum
from Positions_Users as PU
    inner join Positions as P on P.PositionID = PU.PositionID
    inner join Users as U on U.UserID = PU.UserID

select @stmt_columns1 = stuff((select ', [' + RowNum + ']' from @Temp_Data for xml path(''), type).value('.', 'nvarchar(max)'), 1, 2, '')
select @stmt_columns2 = stuff((select ', [' + RowNum + '] as Position' + RowNum from @Temp_Data for xml path(''), type).value('.', 'nvarchar(max)'), 1, 2, '')

select @stmt = '
select
    UserID,
    UserName,' + @stmt_columns2 + '
from
(
    select
        U.UserID, U.UserName, P.PositionName,
        row_number() over (partition by U.UserID order by P.PositionName) as RowNum
    from Positions_Users as PU
        inner join Positions as P on P.PositionID = PU.PositionID
        inner join Users as U on U.UserID = PU.UserID
) as P
    pivot
    (
        min(P.PositionName)
        for P.RowNum in (' + @stmt_columns1 + ')
    ) as PIV'

exec sp_executesql @stmt = @stmt

SQL 小提琴

于 2012-11-27T11:30:11.810 回答