1

まず、中途半端なタイトルですみません。その面では多くの成功を収めていませんでした。

だから - 私は、人が予定されているボランティアシフトごとに 1 つの行を持つデータのテーブルを持っています。時間に寛大な多くの人が、複数のシフトにサインアップしています。私が望むのは、このデータ st を PIVOT することです。最終的には、1あたり 1 行になり、シフトごとに一連の列が作成されます。これまでに約 90 分を費やしましたが、集計関数を適用せずに PIVOT する方法がわかりません。

つまり、各人には少なくとも 1 つのシフトが予定されているため、各人の行には一意の ID、名前、電話番号、および地域が含まれます。次に、Shift1 の一連の列 (役割/ステータス/開始時間/終了時間など) があります。- 全員が少なくとも 1 つのシフトにサインアップしたため、全員が記入したはずです。次に、列の Shift2 セットには 2 つ以上のシフトにサインアップしたユーザーが入力され、Shift3 には 3 つ以上のシフトにサインアップしたユーザーが入力されます。

私の現在のテーブルスキーマ:

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、、、、およびFirstNameを除くすべてLastNameの列はシフト固有です。PhoneRegion

理想的な世界では、次のようなテーブルになります。

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 に答える