2

以下のような日付の列を移動するにはどうすればよいですか。

User              Date
====              ====
001               2012/12/01 09:00
001               2012/12/01 11:00
001               2012/12/01 12:00
001               2012/12/01 13:00
001..             ...        

以下のようにリストしてください。

User  date         time1   time2   time3  time4    time5  
001   2012/12/01   09:00   11:00   12:00  13:00    14:00   

解決策を提供してくれたBluefeetに感謝します。スクリプトをテストしたところ、次の結果が得られました。

2   2012/11/04  09:00:00.000    NULL    NULL    NULL    NULL    NULL    NULL
2   2012/11/08  NULL    09:00:00.000    18:00:00.000    NULL    NULL    NULL    NULL
2   2012/11/09  NULL    NULL    NULL    09:00:00.000    18:00:00.000    NULL    NULL
2   2012/11/10  NULL    NULL    NULL    NULL    NULL    09:00:00.000    18:00:00.000

次の日付で同じユーザーの最後のnull列にスキップするようです。同じユーザーの次の日付の最初の列から順番に並べる方法はありますか?

4

1 に答える 1

4

使用している RDBMS を指定していませんでしたが、以前に質問に sql server タグを付けたので、それがデータベースであると仮定します。

この操作はPIVOT、SQL Server の関数を使用して実行できます。これを行うには、すべての値をハードコーディングする静的方法と、実行時に値が決定される動的方法の 2 つがあります。

静的ピボット:

select *
from 
(
  select [user], convert(varchar(10), date, 111) date,
    right(convert(varchar(50), date, 121), 12) time
    , 'time'+cast(row_number() over(partition by [user], convert(varchar(10), date, 111) order by date) as varchar(10)) rn
  from yourtable
) src
pivot
(
  max(time)
  for rn in (time1, time2, time3, time4)
) piv

デモで SQL Fiddle を参照してください

動的ピボット:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('time'+cast(row_number() over(partition by [user], convert(varchar(10), date, 111) order by date) as varchar(10))) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT [user], date,' + @cols + ' from 
             (
                select [user], convert(varchar(10), date, 111) date,
                  right(convert(varchar(50), date, 121), 12) time
                  , ''time''+cast(row_number() over(partition by [user], convert(varchar(10), date, 111) order by date) as varchar(10)) rn
                from yourtable
            ) x
            pivot 
            (
                max(time)
                for rn in (' + @cols + ')
            ) p '

execute(@query)

デモで SQL Fiddle を参照してください

集計/CASE バージョン:

何らかの理由で関数を使用したくない場合は、ステートメントPIVOTで集計関数を使用することもできます。CASE

select [user], date,
  max(case when rn = 1 then time end) Time1,
  max(case when rn = 2 then time end) Time2,
  max(case when rn = 3 then time end) Time3,
  max(case when rn = 4 then time end) Time4
from
(
  select [user], convert(varchar(10), date, 111) date,
    right(convert(varchar(50), date, 121), 12) time
    , row_number() over(partition by [user], convert(varchar(10), date, 111) order by date)) rn
  from yourtable
) src
group by [user], date

デモで SQL Fiddle を参照してください

3 つすべてで同じ結果が得られます。

| USER |       DATE |        TIME1 |        TIME2 |        TIME3 |        TIME4 |
---------------------------------------------------------------------------------
|  001 | 2012/12/01 | 09:00:00.000 | 11:00:00.000 | 12:00:00.000 | 13:00:00.000 |
|  001 | 2012/12/02 | 09:00:00.000 | 11:00:00.000 | 12:00:00.000 | 13:00:00.000 |
于 2012-12-11T11:08:04.310 に答える