我的表结构是..
Id UserId EventId
1 1 A
2 1 B
3 1 C
4 1 A
5 1 D
我需要的输出..
UserId EventStart EventEnd
1 A B
1 B C
1 C A
1 A D
我希望每两行合并成一行,所以如果第一行有A而第二行有B,那么结果表的第一行有A&乙..
我已经调查了PIVOT,但无法弄清楚如何得到我想要的结果..
如果我可以用sql解决这个问题,如果它必须在中间层解决,我会很高兴,我使用C#
真心感谢任何帮助。
谢谢..
答案 0 :(得分:2)
假设您有一个指定排序的id列,您可以使用lead()
(在SQL Server 2012 +中)获得所需内容:
select userId, eventid as eventstart,
lead(eventid) over (partition by userid order by id) as eventend
from mytable t;
您要过滤掉最后一行,您可以使用子查询(where
子句中不允许使用窗口函数):
select t.*
from (select userId, eventid as eventstart,
lead(eventid) over (partition by userid order by id) as eventend
from mytable t
) t
where eventend is null;
在早期版本的SQL Server中,您可以通过其他方式获得相同的效果,例如相关子查询或交叉应用。这是一个例子:
select t.*
from (select userId, eventid as eventstart,
(select top 1 t2.eventid
from mytable t2
where t2.userid = t.userid and
t2.id > t.id
order by t2.id
) as eventend
from mytable t
) t
where eventend is not null;
答案 1 :(得分:1)
一种简单的方法是在ID上使用生成的Row_Number()的CTE,并通过UserID和Rownumber加入。
declare @t Table([ID] [int] IDENTITY(1,1) NOT NULL, UserID int,EventID varchar(10))
insert into @t
Select 1,'A'
UNION ALL Select 1,'B'
UNION ALL Select 1,'C'
UNION ALL Select 1,'A'
UNION ALL Select 1,'D'
UNION ALL Select 2,'B'
UNION ALL Select 2,'C'
UNION ALL Select 2,'A'
UNION ALL Select 2,'D'
;With c as
(
Select UserID,EventID,Row_Number() OVER (Order by UserID,ID ) as RN
from @t
)
Select c1.UserID,c1.EventID as EventStart ,c2.EventID as EventEnd
from c c1
Join c c2 on c2.RN=c1.RN+1 and c2.UserID=c1.UserID