C# 在SQL Server中每两行合并一列中的数据

C# 在SQL Server中每两行合并一列中的数据,c#,sql,sql-server,linq,linq-to-sql,C#,Sql,Sql Server,Linq,Linq To Sql,我的桌子结构是 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

我的桌子结构是

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&B

我已经研究了PIVOT,但无法找出如何获得我想要的结果

如果我能用SQL Suffor来解决这个问题,那就太好了,如果它必须在中间层解决的话,我就用C<

衷心感谢您的帮助


谢谢。

假设您有一个id列来指定顺序,您可以使用
lead()
(在SQL Server 2012+中)获得所需的内容:

您正在过滤掉最后一行,这可以通过子查询完成(在
where
子句中不允许使用窗口函数):

在早期版本的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;

一种简单的方法是使用一个CTE,在ID上生成一个Row_Number(),然后在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

请详细说明您的问题。您如何定义EvntStart和EventEnd???请详细解释…编辑了问题,请务必告知其是否清楚..Tx..SQL表表示无序集。除非列指定了顺序,否则表中没有“下一行”。您的表是否有包含此信息的id或创建日期列?我有id和创建日期,我认为它们不是必需的,因此没有添加到结构中..我在本地有sql server 2008,但我将在sql azure上托管,为了进行测试,我正在使用相关子查询-这里的“我的表名”将替换t或t2?我认为查询的最后一部分应该是“where eventend不为null;”@阿玛布。我完全误解了你的评论。很抱歉,你当然是对的。你知道为什么Or子句在where子句中不起作用吗..我试过“where eventstart!='A'”-这有效,但当我试过“where eventstart!='A'或eventstart!='B'”-这不起作用..@Amab。我不知道你的问题是指什么。但是如果你既不想要A也不想要B,只需使用
不在
事件开始不在('A','B')
。我有8462行64个用户的数据..只需回答的底部部分,我就得到5084行,这更少..是的,现在我得到的结果与Gordon Tx的答案相同
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;
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