2013-06-28 50 views
1

我正在將源表中的記錄和列的子集導入到本地表中。我正在嘗試摺疊這些數據,以便我的表格中可以有唯一的行,但只有當日期範圍連續時纔有。我遇到了麻煩,因爲我無法弄清楚如何進行分組,以免跳過日期範圍。下面是一些示例數據:如何分組行,但只能在sql服務器中的非脫節日期範圍t-sql


|PID | GroupID | Data | StartDate | EndDate 
| 12 |  1 | 4 |  45 |  50 
| 11 |  1 | 5 |  40 |  45 
| 10 |  1 | 5 |  35 |  40 
| 9 |  1 | 4 |  30 |  35 
| 8 |  2 | 5 |  25 |  50 
| 7 |  1 | 4 |  25 |  30 
| 6 |  1 | 4 |  20 |  25 
| 5 |  1 | 2 |  15 |  20 
| 4 |  1 | 3 |  10 |  15 
| 3 |  1 | 3 |   5 |  10 
| 2 |  2 | 1 |   1 |  25 
| 1 |  1 | 2 |   1 |  5 

我試圖得到這樣的結果:


|GroupID | HistoryID | Data | StartDate | EndDate 
|  1 |   1 | 4 |  45 |  50 
|  1 |   2 | 5 |  35 |  45 
|  1 |   3 | 4 |  20 |  35 
|  1 |   4 | 2 |  15 |  20 
|  1 |   5 | 3 |   5 |  15 
|  1 |   6 | 2 |   1 |  5 
|  2 |   1 | 5 |  25 |  50 
|  2 |   2 | 1 |   1 |  25 

所以,想象一下有上千組ID的data列實際上是多列和開始/結束日期實際日期。

我想要做的是通過自己加入startDateendDate並比較數據,或者做某種partion by groupid和對數據進行分組的某種解決方案。然後取最小值startDate和最大值endDate。然而,我不能找出一種方法,使數據4不會從20 startdate到50 enddate,並重疊數據5的日期範圍。

我知道在Sql Server 2012中有一些用於預測的新東西行和運行總數,但我在Sql Server 2008中實現。任何想法?

+1

可能是範圍之間的差距?例如,有兩個範圍20-25 30-35,沒有範圍25-30?如果是這樣,如果記錄在範圍之間有差距,那麼記錄是否在一個組中? – Alexey

+0

儘管可以在sql中執行此操作,但無論您使用哪種編程語言進行後處理,它都會變得更容易 - 您必須在sql中執行多次連接。 –

+0

是的,即時通訊我可以做很多方法,包括手工,但我需要的解決方案是t-sql。我想它涉及到一些常見的表達式,以及group和by或rank或row_number函數的一些聰明用法。我只是不能完全弄清楚它。我列出了問題的參數和期望的解決方案。最好沒有解決方案引入遊標。 – vernmic

回答

1

如果範圍之間的差距是不可能的,或者如果他們不打破一組則:

------------ 
-- test data 
------------ 
declare @data table 
(
    Pid int, 
    GroupID int, 
    Data int, 
    StartDate int, 
    EndDate int 
) 

insert into @data (Pid, GroupID, Data, StartDate, EndDate) 
values 
(10, 1, 4, 45, 50), 
(9, 1, 5, 40, 45), 
(8, 1, 5, 35, 40), 
(7, 1, 4, 30, 35), 
(6, 1, 4, 25, 30), 
(5, 1, 4, 20, 25), 
(4, 1, 2, 15, 20), 
(3, 1, 3, 10, 15), 
(2, 1, 3, 5, 10), 
(1, 1, 2, 1, 5) 


----------- 
-- solution 
----------- 
select 
    GroupID, Data, StartDate = min(StartDate), EndDate = max(EndDate) 
from 
(
    select 
     *, 
     rn1 = row_number() over(order by StartDate), 
     rn2 = row_number() over(partition by GroupID, Data order by StartDate desc) 
    from @data 
) t 
group by GroupID, Data, rn1 + rn2 
order by StartDate desc 

否則,請讓我知道。

+0

非常聰明的日期asc和desc。 rn1需要通過groupid進行分區,最後的選擇需要rownumber以groupid進行分區來創建historyid列(groupid,historyId成爲新的主鍵),並且通過historyid = 1進行過濾是我的新表中爲所有組的最新選擇記錄。但除此之外,這個解決方案效果很好,謝謝Alexey – vernmic