1

首先,对不起这个中等标题。在这方面没有取得很大的成功。

所以 - 我有一个数据表,其中一个人计划的每个志愿者轮班都有一行。许多人,因为他们的时间很慷慨,已经报名参加了多次轮班。我想要的是 PIVOT 这个数据,我最终得到每人一行每个班次都有一组列。到目前为止,我已经花了大约 90 分钟,但无法弄清楚如何在没有应用聚合函数的情况下进行 PIVOT。

我的意思是每个人都安排至少一个班次,所以每个人的行都会有他们唯一的 ID、他们的姓名、他们的电话号码和他们的地区。然后会有一组 Shift1 的列 - 角色/状态/开始时间/结束时间/等。- 因为每个人都已经报名了至少一个班次,所以每个人都会填写。然后,将为已注册 2+ 班次的人填充 Shift2 列集,为已注册 3+ 班次的人填充 Shift3 等。

我当前的表架构:

CREATE TABLE [dbo].[confirmexport](
    [PersonID] [int] NULL,
    [EventType] [varchar](14) NULL,
    [Shift] [varchar](10) NULL,
    [StartDate] [datetime] NULL,
    [StartTime] [datetime] NULL,
    [EndDate] [datetime] NULL,
    [EndTime] [datetime] NULL,
    [Location] [varchar](39) NULL,
    [Role] [varchar](16) NULL,
    [Status] [varchar](9) NULL,
    [FirstName] [varchar](20) NULL,
    [LastName] [varchar](22) NULL,
    [Phone] [bigint] NULL,
    [Region] [varchar](9) NULL
) ON [PRIMARY]

PersonID除、FirstNameLastNamePhone和之外的所有列Region都是班次特定的。

在一个理想的世界中,我最终会得到一张看起来像这样的表格:

CREATE TABLE [dbo].[confirmexportpivoted](
    [PersonID] [int] NULL,
    [Phone] [bigint] NULL,
    [FirstName] [varchar](20) NULL,
    [LastName] [varchar](22) NULL,
    [Region] [varchar](9) NULL,
    [EventType1] [varchar](14) NULL,
    [Shift1] [varchar](10) NULL,
    [StartDate1] [datetime] NULL,
    [StartTime1] [datetime] NULL,
    [EndDate1] [datetime] NULL,
    [EndTime1] [datetime] NULL,
    [Location1] [varchar](39) NULL,
    [Role1] [varchar](16) NULL,
    [Status1] [varchar](9) NULL,
    [EventType2] [varchar](14) NULL,
    [Shift2] [varchar](10) NULL,
    [StartDate2] [datetime] NULL,
    [StartTime2] [datetime] NULL,
    [EndDate2] [datetime] NULL,
    [EndTime2] [datetime] NULL,
    [Location2] [varchar](39) NULL,
    [Role2] [varchar](16) NULL,
    [Status2] [varchar](9) NULL
) ON [PRIMARY]

除了我的数据所需的尽可能多的列集。或者 - 如果这是一个交易破坏者,我绝对可以使用 3。有什么建议吗?

在此先感谢-我非常困惑,希望能提供任何帮助。

4

1 回答 1

2

嗯,我很难重现整个表格,所以我只使用了开始和结束日期和时间,但解决方案应该适用于任意数量的列。您可以在 SQL FIDDLE 中对其进行测试

SQL 提琴示例

declare @columns nvarchar(max), @stmt nvarchar(max)
declare @Temp_Columns table (RowNum int, COLUMN_NAME nvarchar(128))

insert into @Temp_Columns
select R.RowNum, c.COLUMN_NAME
from
(
    select row_number() over (partition by c.PersonID, c.FirstName, c.LastName, c.Phone, c.Region order by c.StartDate asc, c.EndDate asc) as RowNum
    from confirmexport as c
) as R
    inner join INFORMATION_SCHEMA.[COLUMNS] as c on c.TABLE_NAME = 'confirmexport' and c.COLUMN_NAME not in ('PersonID', 'FirstName', 'LastName')
order by 1, 2

select @columns = isnull(@columns + ', ', '') + 
    'min(case when A.RowNum = ' + cast(T.RowNum as nvarchar(128)) + 
    ' then A.[' + T.COLUMN_NAME + '] else null end) as [' + 
    T.COLUMN_NAME + cast(T.RowNum as nvarchar(128)) + ']'
from @Temp_Columns as T

select @stmt = '
select
    A.PersonId, A.FirstName, A.LastName, A.Phone, A.Region,' + @columns + '
from
(
    select
        c.*,
        row_number() over (partition by c.PersonID, c.FirstName, c.LastName, c.Phone, c.Region order by c.StartDate asc, c.EndDate asc) as RowNum
    from confirmexport as c
) as A
group by
    A.PersonId, A.FirstName, A.LastName, A.Phone, A.Region'

exec sp_executesql
    @stmt = @stmt
于 2012-11-03T20:28:55.053 回答