使用不带任何子句的 Pivot 将行转换为列

convert row to column using Pivot without any clause

我有一个 table 如下所示。

我需要获取如下数据。

我创建了两个临时 tables 并取得了这样的结果。请帮我用 PIVOT 做同样的事情。

至少我不会为此使用 pivot,在我看来,使用 group by 和 row_number:

更简单
select UserId, max(starttime) as starttime, max(endtime) as endtime
from (
  select UserId,
    case when StartOrEnd = 'S' then time end as starttime,
    case when StartOrEnd = 'E' then time end as endtime,
    row_number() over (partition by UserID order by time asc) 
      + case when StartOrEnd = 'S' then 1 else 0 end as GRP
  from table1
) X
group by UserId, GRP
order by starttime

派生的 table 将时间拆分为开始/结束时间列(以处理只有一个存在的情况)并使用带有行号的技巧将 S / E 项目组合在一起。外部 select 只是将行分组到同一行。

SQL Fiddle

中的示例

不像 JamesZ 那样是一个有效的解决方案,但应该可行

create table #tst (userid int,start_end char(1),times datetime)
insert #tst values
(1,'S','07-27-2015 16:45'),
(1,'E','07-27-2015 16:46'),
(2,'S','07-27-2015 16:47'),
(2,'E','07-27-2015 16:48'),
(1,'S','07-27-2015 16:49'),
(1,'E','07-27-2015 16:50')

WITH cte
     AS (SELECT Row_number()OVER(ORDER BY times) rn,*
         FROM   #tst),
     cte1
     AS (SELECT a.userid,
                a.start_end,
                a.times,
                CASE WHEN a.userid = b.userid THEN 0 ELSE 1 END AS com,
                a.rn
         FROM   cte a
                LEFT OUTER JOIN cte b
                             ON a.rn = b.rn + 1),
     cte2
     AS (SELECT userid,
                start_end,
                times,
                (SELECT Sum(com)
                 FROM   cte1 b
                 WHERE  b.rn <= a.rn) AS row_num
         FROM   cte1 a)
SELECT USERID,
       starttime=Min(CASE WHEN start_end = 's' THEN times END),
       endtime=Max(CASE WHEN start_end = 'e' THEN times END)
FROM   cte2
GROUP  BY USERID,
          row_num  

还有一个方法

declare @t table(userid int, StartOrEnd char(1),  time datetime)
insert into @t
select 1,'S','2015-07-27 16:45' union all
select 1,'E','2015-07-27 16:46' union all
select 2,'S','2015-07-27 16:47' union all
select 2,'E','2015-07-27 16:48' union all
select 1,'S','2015-07-27 16:49' union all
select 1,'E','2015-07-27 16:50'

select userid,min(time) as minimum_time, max(time) as maximum_time from
(
select *, row_number() over (partition by cast(UserID as varchar(10))
          +StartOrEnd order by time asc) as sno
from @t      
) as t
group by userid,sno

结果

userid      minimum_time            maximum_time
----------- ----------------------- -----------------------
1           2015-07-27 16:45:00.000 2015-07-27 16:46:00.000
2           2015-07-27 16:47:00.000 2015-07-27 16:48:00.000
1           2015-07-27 16:49:00.000 2015-07-27 16:50:00.000