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

时间似乎跳到下一个日期同一用户的最后一个空列?有没有办法让我从第一列开始为同一用户安排下一个日期的顺序?

4

1 回答 1

4

您没有指定您使用的是什么 RDBMS,但您之前使用 sql server 标记标记了问题,所以我假设那是数据库。

PIVOT您可以使用SQL Server 中的函数执行此操作。有两种方法可以做到这一点,一种是对所有值进行硬编码的静态方法,另一种是在运行时确定值的动态方法。

静态枢轴:

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

聚合/案例版本:

如果由于某种原因您不想使用该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

这三个产生相同的结果:

| 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 回答