2014-04-04 74 views
1

我嘗試編寫一個將活動數據轉移到彙總行的查詢。例如輸入數據是活動日期,描述和狀態;如果是信息行,則啓動,停止或爲空。SQL查詢數據透視數據2行變爲1

這是數據格式的例子:

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 

我想所有的開始,並把corrosponding停止在同一行作爲activity_start_date等和activity_stop_date。

我的問題是我想要在每次開始之後的第一站,我已經完成了,但是我也想忽略開始之前有一個開始。對於瞬間開始,停止,停止,開始,開始,停止,開始將返回;開始停止,開始停止,開始空。

我已經嘗試了一個左連接加入第一站後開始,但這也包括第二次匹配兩次相同的停止。

我以爲我需要臨時表,但我認爲這是不必要的。日期變量是否會在第一次啓動設置變量的地方工作,然後停止是設置變量的變量之後的第一站,而下一次啓動是新設置變量之後的第一次啓動?

您的幫助表示讚賞!

這是我到目前爲止有:

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

你嘗試過使用PIVOT函數來完成? http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx – user1800552

+0

我不認爲這將工作,因爲我只想在開始後的第一個停止日期忽略所有的開始這以前有一個開始。 – Danny306

+2

您使用的是哪個版本的SQL Server? – CElliott

回答

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。

0

shriop的查詢幾乎是正確的,它失敗的地方有以下幾行,如,如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可以按行編號和自模擬聯接