首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL查询透视数据%2行为%1

SQL查询透视数据%2行为%1
EN

Stack Overflow用户
提问于 2014-04-04 18:58:23
回答 2查看 117关注 0票数 1

我正在尝试编写一个将活动数据转换为汇总行的查询。例如,输入数据为activity date、description和status;如果是信息性行,则为Start、Stop或null。

以下是数据格式的示例:

代码语言:javascript
复制
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

这是预期的结果:

代码语言:javascript
复制
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,Stop,Start,Start,Stop,Start将返回;Start Stop,Start Stop,Start null。

我尝试了一个左连接来加入一个开始后的第一个停止,但这也包括第二个开始匹配相同的停止两次。

我想我需要一个临时表,但我认为这是不必要的。当第一个开始设置变量,然后停止是设置变量的变量之后的第一个停止,而下一个开始是新的设置变量之后的第一个开始时,日期变量是否有效?

感谢您的帮助!

这就是我到目前为止所知道的:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2014-05-23 11:44:28

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2014-05-23 17:25:21

shriop的查询几乎是正确的,如果有像2205和2528这样的ActivityType = 'Start'行,它就会失败。对于那些,需要删除重复的行(具有相同ActivityType的先例的行)。

如果操作人员使用SQLServer 2012或更高版本,则可以使用LAG完成此操作

代码语言:javascript
复制
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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22860876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档