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

时间:2015-07-27 11:40:17

标签: sql sql-server sql-server-2008-r2 pivot

我有一张如下表格。

enter image description here

我需要获取如下数据。

enter image description here

我创建了两个临时表,并实现了这样的结果。请帮我用PIVOT做同样的事。

3 个答案:

答案 0 :(得分:4)

至少我不会使用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

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

SQL Fiddle

中的示例

答案 1 :(得分:0)

不像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  

答案 2 :(得分:0)

这是另一种方法

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