我怎样才能收集这些数据?

时间:2012-11-03 19:51:46

标签: sql sql-server tsql pivot

首先,对于中等冠军感到抱歉。在这方面没有取得多大成功。

所以 - 我有一个数据表,每个志愿者班次都有一行。许多人慷慨地花时间报名参加了多次轮班。我想要的是PIVOT这个数据s.t.我最终每个一行,每个班次都有一组列。到目前为止,我已经花费了大约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]

PersonIDFirstNameLastNamePhoneRegion之外的所有列都是特定于班次的。

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

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.任何建议?

提前致谢 - 我非常困惑,非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

那么我很难重现整个表格,所以我只使用了Start和End Dates and Times,但解决方案应该适用于任意数量的列。您可以在SQL FIDDLE

中测试它

SQL FIDDLE EXAMPLE

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