2013-12-17 23 views
1

編輯:很多需要澄清的事實是名稱可以有多對非重疊的開始和結束。所以合併對可以被識別爲「運行」。將具有一個DateTime列的行合併到具有開始日期列和結束日期列的單行中

我猜這是一個重複的問題,但我似乎無法找到另一個。如果有人能指出我的意思,那麼這可以關閉或刪除或其他任何東西。

我有一個表,看起來像這樣:


Id Name  Action  ActionDate 
---- ------- ------  ---------- 
1 John  Start  01/15/2013 
2 Mary  Start  01/17/2013 
3 Nancy  Start  01/17/2013 
4 John  End   01/18/2013 
5 Mary  End   01/18/2013 
6 Nancy  End   01/20/2013 
7 John  Start  01/19/2013 
8 Mary  Start  01/20/2013 
9 Nancy  Start  01/25/2013 
10 John  End   01/21/2013 
11 Mary  End   01/22/2013 
12 Nancy  End   01/30/2013 

而我需要的結果集看起來像這樣使用一組基於查詢:


Id Name Run StartActionDate EndActionDate 
---- ------- ---- --------------- ------------- 
1 John 1  01/15/2013   01/18/2013 
2 John 2  01/19/2013   01/21/2013 
3 Mary 1  01/17/2013   01/18/2013 
4 Mary 2  01/20/2013   01/22/2013 
5 Nancy 1  01/17/2013   01/20/2013 
6 Nancy 2  01/25/2013   01/30/2013 
+0

您的名字會有多個行動/日期對嗎? – Taryn

+0

'名稱'是否是唯一的?如果不是,結果將不可靠。 – Mike

+0

是的,一個名字將有許多開始和結束對。是的,在結果集中,名稱將是唯一的。 –

回答

0

檢查了這一點

select MIN(Id),Name,MIN(case Action when 'Start' then ActionDate End) as StartActionDate,MIN(case Action When 'End' then ActionDate End) as EndActiondate from dbo.Table group by Name 
+0

非常感謝Anjali,我會更新這個問題,但每個名稱不只有一個開始和結束日期。名字開始和結束許多次。 –

0

假設每個Name只有1個「Start」記錄和1個「End」記錄,應該像這樣RK:

SELECT T1.Id, T1.Name, T1.ActionDate AS [StartActionDate], T2.ActionDate AS [EndActionDate] 
FROM MyTable T1 
INNER JOIN MyTable T2 ON T1.Name = T2.Name 
WHERE T1.Action = 'Start' AND T2.Action = 'End' 
+0

謝謝丹,我會更新這個問題,但是每個名稱不只有一個開始和結束日期。名字開始和結束許多次。 –

+0

那麼你想輸出最小的startdate和最大的enddate,還是需要輸出每個相鄰的startdates和enddates?在後一種情況下,關於潛在的重疊時期? – Dan

+0

相鄰對,不重疊。 –

0

雖然它不是很清楚你想回到如果您有多個對每個name什麼id,你應該能夠使用窗口函數像row_number()產生與動作每個名稱的唯一序列然後生成最終的結果:

;with cte as 
(
    select id, name, action, actiondate, 
    row_number() over(partition by name, action 
         order by actiondate) seq 
    from yourtable 
) 
select 
    min(id) id, 
    name, 
    max(case when action = 'start' then actiondate end) StartActionDate, 
    max(case when action = 'end' then actiondate end) EndActionDate 
from cte 
group by name, seq 
order by id; 

SQL Fiddle with Demo

根據您的數據的變化,你應該能夠使用類似的東西:

;with cte as 
(
    select id, name, action, actiondate, 
    row_number() over(partition by name, action 
         order by actiondate) seq 
    from yourtable 
) 
select 
    row_number() over(order by name) id, 
    name, 
    seq run, 
    max(case when action = 'start' then actiondate end) StartActionDate, 
    max(case when action = 'end' then actiondate end) EndActionDate 
from cte 
group by name, seq 
order by id 

請參閱SQL Fiddle with Demo。這給出了一個結果:

| ID | NAME | RUN |    STARTACTIONDATE |     ENDACTIONDATE | 
|----|-------|-----|--------------------------------|--------------------------------| 
| 1 | John | 1 | January, 15 2013 00:00:00+0000 | January, 18 2013 00:00:00+0000 | 
| 2 | John | 2 | January, 19 2013 00:00:00+0000 | January, 21 2013 00:00:00+0000 | 
| 3 | Mary | 1 | January, 17 2013 00:00:00+0000 | January, 18 2013 00:00:00+0000 | 
| 4 | Mary | 2 | January, 20 2013 00:00:00+0000 | January, 22 2013 00:00:00+0000 | 
| 5 | Nancy | 1 | January, 17 2013 00:00:00+0000 | January, 20 2013 00:00:00+0000 | 
| 6 | Nancy | 2 | January, 25 2013 00:00:00+0000 | January, 30 2013 00:00:00+0000 | 
相關問題