尝试在不使用游标

时间:2015-10-13 18:37:29

标签: sql-server

我有下表:

enter image description here

我想要的是:

enter image description here

EventTypeId 1和3是有效的开始事件,EventTypeId的2是唯一有效的结束事件。

我试图做一个支点,但我不相信一个支点会让我得到结果集中一个人的多个事件。

SELECT PersonId, [1],[3],[2] 
FROM 
    (
    SELECT PersonId, EventTypeId, EventDate 
    from #PersonEvent
    ) as SourceTable 
PIVOT 
    (
    count(EventDate) FOR EventTypeId 
    IN ([1],[3],[2]) 
    ) as PivotTable 

Select PersonID, 
    Min(Case WHEN EventTypeId IN (1,3) THEN EventDate END) as StartDate, 
    Min(Case WHEN EventTypeId IN (2) THEN EventDate END) as EndDate 
FROM #PersonEvent 
group by personid

我可以做一个光标,但我的原始表格超过90,000行,这是一个报告,所以我不认为我可以使用该选项。我可能会遗失任何其他想法吗?

2 个答案:

答案 0 :(得分:2)

假设该表名为[dbo].[PersonEventRecords],这将有效......

With    StartEvents As
(
        Select  *
        From    [dbo].[PersonEventRecords]
            Where   EventTypeId In (1,3)
),      EndEvents As
(
        Select  *
        From    [dbo].[PersonEventRecords]
        Where   EventTypeId In (2)
)
Select  IsNull(se.PersonId,ee.PersonId) As PersonId, 
        se.EventTypeId As StartEventTypeId,
        se.EventDate As StartEventDate, 
        ee.EventTypeId As EndEventTypeId,
        ee.EventDate As EndEventDate
From    StartEvents se
Full    Outer Join  EndEvents ee
        On  se.PersonId = ee.PersonId
        And se.EventSequence = ee.EventSequence - 1
Order   By IsNull(se.PersonId,ee.PersonId),
        IsNull(se.EventDate,ee.EventDate);


/**** TEST DATA ****/
If      Object_ID('[dbo].[PersonEventRecords]') Is Not Null 
            Drop Table [dbo].[PersonEventRecords];

Create  Table [dbo].[PersonEventRecords] 
    (
        PersonId Int,
        EventTypeId Int,
        EventDate Date,
        EventSequence Int
    );

Insert  [dbo].[PersonEventRecords]
Select  1,1,'2012-10-13',1
Union All
Select  1,2,'2012-10-20',2
Union All
Select  1,1,'2012-11-01',3
Union All
Select  1,2,'2012-11-13',4
Union All
Select  2,1,'2012-05-07',1
Union All
Select  2,2,'2012-06-01',2
Union All
Select  2,3,'2012-07-01',3
Union All
Select  2,2,'2012-08-30',4
Union All
Select  3,2,'2012-04-05',1
Union All
Select  3,1,'2012-05-04',2
Union All
Select  3,2,'2012-05-24',3
Union All
Select  4,1,'2013-01-03',1
Union All
Select  4,1,'2013-02-20',2
Union All
Select  4,2,'2013-03-20',3;

答案 1 :(得分:0)

试试这个

SELECT E1.PersonId, E1.EventTypeId, E1.EventDate, E2.EventTypeId, E2.EventDate
FROM PersonEvent AS E1
OUTER APPLY(
    SELECT TOP 1 PersonEvent.EventTypeId, PersonEvent.EventDate
    FROM PersonEvent
    WHERE PersonEvent.PersonId = E1.PersonId
        AND PersonEvent.EventSequence = E1.EventSequence + 1
        AND PersonEvent.EventTypeId = 2
) AS E2
WHERE E1.EventTypeId = 1 OR E1.EventTypeId = 3

UNION

SELECT E3.PersonId, NULL, NULL, E3.EventTypeId, E3.EventDate
FROM PersonEvent E3
WHERE E3.EventTypeId = 2
AND NOT EXISTS(
    SELECT *
    FROM PersonEvent
    WHERE PersonEvent.PersonId = E3.PersonId
    AND PersonEvent.EventSequence = E3.EventSequence - 1)

目前还不完全清楚如何订购结果 - 根据需要添加订单。