我尝试编写一个查询,将活动数据转换为摘要行。例如,输入数据是活动日期,描述和状态;如果它是信息性行,则启动,停止或为null。
这是数据格式的一个例子:
ID | ActivityID | ActivityType | ActivityDate | Status | Activity
----------------------------------------------------------------------
701 | 26 | Start | 02/07/13 15:16 | 10 | Run Job
728 | 26 | No Change | 05/07/13 09:30 | 20 | Running
859 | 26 | Stop | 22/07/13 12:45 | 30 | Error
1064 | 26 | Start | 10/08/13 13:26 | 11 | Restarted
1524 | 26 | Stop | 28/08/13 10:19 | 31 | Error
1785 | 26 | Stop | 07/09/13 11:48 | 31 | Error
2205 | 26 | Start | 17/09/13 09:05 | 10 | Restarted
2528 | 26 | Start | 14/10/13 17:56 | 11 | Restarted
2528 | 26 | Stop | 25/10/13 20:47 | 32 | Completed
这是预期的结果:
ActivityID | Start_Type | Start_Date | Start_Status | Start_Activity | Stop_Type | Stop_Date | Stop_Status | Stop_Activity
---------------------------------------------------------------------------------
26 | Start | 02/07/13 15:16 | 10 | Run Job | Stop | 22/07/13 12:45 | 30 | Error
26 | Start | 10/08/13 13:26 | 11 | Restarted | Stop | 28/08/13 10:19 | 31 | Error
26 | Start | 17/09/13 09:05 | 10 | Restarted | Stop | 25/10/13 20:47 | 32 | Done
我希望得到所有的开始,并将反应停止与activity_start_date等和activity_stop_date放在同一行。
我的问题是我希望每次开始后我都做了第一站,但是我也想忽略一个在它之前有一个开始的开始。对于瞬间启动,停止,停止,启动,启动,停止,启动将返回; Start Stop,Start Stop,Start null。
我尝试了一个左连接,在开始后加入第一站,但这也包括第二次开始匹配同一个停止两次。
我以为我需要临时表,但我认为这是不必要的。日期变量是否适用于第一个开始设置变量的位置,然后停止是设置变量的变量之后的第一个停止,下一个开始是新设置变量之后的第一个开始?
感谢您的帮助!
这是我到目前为止所做的:
SELECT
activity.ID,
activity.ActivityType AS StartActivityType,
activity.ActivityDate AS StartActivityDate,
activity.Status AS StartStatus,
activity.Activity AS StartActivity,
activity2.ActivityType AS StopActivityType,
activity2.ActivityDate AS StopActivityDate,
activity2.Status AS StopStatus,
activity2.Activity AS StopActivity
FROM tempdb..#TempTable activity
FULL OUTER JOIN #TempTable activity2
ON activity.ID = activity2.ID
AND activity2.ActivityType = 'Stop'
AND (activity2.ActivityDate > activity.ActivityDate)
AND (activity2.ActivityDate = ( SELECT MIN(activity3.ActivityDate)
FROM tempdb..#TempTable activity3
WHERE activity.ID = activity2.ID
AND activity3.ActivityType = 'Stop'
AND activity3.ActivityDate > activity.ActivityDate))
WHERE activity.ActivityType = 'Start'
--does not have a start before
AND activity.ActivityDate > ( SELECT MAX(activity3.ActivityDate)
FROM tempdb..#TempTable activity2
WHERE activity2.PathwayID = activity.ID
AND activity2.ActivityType IN ('Stop','Start')
AND activity2.ActivityDate > activity.ActivityDate))
--AND activity2.ActivityDate != LAG(activity2.ActivityDate) OVER (ORDER BY activity.ActivityDate),
--AND activity.ActivityDate IS NULL
ORDER BY activity.ID ASC
答案 0 :(得分:1)
select * from #TempTable a1
cross apply
(
select top 1 *
from
#TempTable a2
where
a2.ActivityType = 'Stop'
and a2.ActivityID = a1.ActivityID
and a2.ActivityDate > a1.ActivityDate
order by
a2.ActivityDate
) a2
where
a1.ActivityType = 'Start'
order by
a1.ActivityDate;
你的数据中有一些我不理解的奇怪之处,但是这应该会让你获得90%,并且它比尝试加入ActivityDate要清晰得多。
答案 1 :(得分:0)
shriop的查询几乎是正确的,它在跟随ActivityType = 'Start'
的后续行(如2205和2528)时失败。对于那些需要删除重复行(具有相同ActivityType的行)。
如果OP使用SQLServer 2012或更高版本,可以使用LAG
WITH DATA AS (
SELECT ActivityID
, ActivityType
, ActivityDate
, Status
, Activity
, LastActivity = LAG(ActivityType, 1, 'Stop') OVER (ORDER BY ActivityDate)
FROM Table1
WHERE ActivityType IN ('Start', 'Stop')
)
SELECT a1.ActivityID
, Start_Type = a1.ActivityType
, Start_Date = a1.ActivityDate
, Start_Status = a1.Status
, Start_Activity = a1.Activity
, Stop_Type = a2.ActivityType
, Stop_Date = a2.ActivityDate
, Stop_Status = a2.Status
, Stop_Activity = a2.Activity
FROM DATA a1
CROSS apply (SELECT top 1 *
FROM Table1 a2
WHERE a2.ActivityType = 'Stop'
AND a2.ActivityID = a1.ActivityID
AND a2.ActivityDate > a1.ActivityDate
ORDER BY a2.ActivityDate) a2
WHERE a1.ActivityType = 'Start'
AND a1.LastActivity <> a1.ActivityType
ORDER BY a1.ActivityDate;
否则可以通过行编号和自联接来模拟LAG