2016-11-02 44 views
3

我有四個字段的表格:ID,DateBeg,DateEndRankIDRankID值爲ID字段的排名,高於DateBeg asc。這裏的樣本數據:分組表問題

ID |RankID | DateBeg | DateEnd | 
---|-------|-------------------------- 
1 | 1  |01-01-2016 |04-01-2016 | 
1 | 2  |05-01-2016 |11-02-2016 | 
1 | 3  |12-02-2016 |15-02-2016 | 
1 | 4  |16-02-2016 |19-02-2016 | 
1 | 5  |23-02-2016 |25-02-2016 | 
4 | 2  |05-01-2016 |07-01-2016 | 
4 | 3  |08-01-2016 |12-01-2016 | 
5 | 1  |04-01-2016 |06-01-2016 | 

現在,我想組ID記錄,其中有DateBeg值1天之前的排名記錄後DateEnd值(如果爲null,它必須包含太)。 這個例子表期望的結果將是:

ID | Min(DateBeg)|Max(DateEnd)| 
---|-------------|---------------- 
1 |01-01-2016 |19-02-2016 | 
1 |23-02-2016 |25-02-2016 | 
4 |05-01-2016 |12-01-2016 | 
5 |04-01-2016 |06-01-2016 | 

希望你能幫助我,在此先感謝。

+0

的SQL Server版本使用的是 –

+0

的SQL Server 2012 –

+0

什麼是RankID呢?這看起來多餘,因爲訂單與日期相同。或者RankID還有其他特殊含義?如果沒有,我會將它從桌子上移開。 –

回答

2

這裏是算法:

  1. 檢測的空白。立即給每個不符合之前記錄的記錄添加一個缺口#1。因此,每個開始一個新組的記錄都將被標記爲#1。
  2. 建立一個間隙號碼的運行總數。因此,一個組的所有記錄都會得到相同的編號。
  3. 按組查找並顯示每個組的最小開始日期和最大結束日期。

SQL Server查詢:

select id, min(datebeg), max(dateend) 
from 
(
    select 
    id, 
    datebeg, 
    dateend, 
    sum(gap) over (partition by id order by datebeg) as grp 
    from 
    (
    select 
     id, 
     datebeg, 
     dateend, 
     case when datebeg <> 
       dateadd(day, 1, lag(dateend) over (partition by id order by datebeg)) 
      then 1 else 0 end as gap 
    from mytable 
) with_gap_flags 
) with_group_numbers 
group by id, grp 
order by id, grp; 

SQL小提琴:http://sqlfiddle.com/#!6/f473ae/1

+0

我正在將我的接受轉移到這個答案上,因爲這個答案非常完整。 –

3

試試像下面這樣。我假設你的datebegDateend是日期數據類型格式。否則,您需要轉換爲日期數據類型進行比較。

SELECT ID,MIN(DATEBEG),MAX(DateEnd) FROM 
    (
    SELECT ID,(DATEBEG),ROW_NUMBER()OVER(PARTITION BY ID ORDER BY ID) RNO, 

    (DateEND),CASE WHEN DATEBEG=LAG(DATEADD(DAY,1,[DateEnd])) 
    OVER(PARTITION BY ID ORDER BY ID)THEN 1 END NO 
    FROM #TABLE1 
    )A 
    GROUP BY ID,ISNULL(NO,RNO) 
    ORDER BY ID 

更新: - 嘗試以下。如果你的數據集中有唯一的ud和rank id組合,那麼它將適用於所有場景,否則使用row_number並生成唯一的數字。

SELECT ID,MIN(DATEBEG),MAX(DATEEND) FROM 
(
SELECT ID, 
     RANKID, 
     datebeg, 
     DateEnd, 
     CASE 
     WHEN Dateadd(DAY, -1, datebeg) = Lag(DateEnd) OVER(PARTITION BY ID ORDER BY ID)               
     OR Dateadd(DAY, 1, dateEND) = LEAD(DateBeg) OVER(PARTITION BY ID ORDER BY ID)              
     THEN 1 
     ELSE 0 
     END NO 
FROM #Table1 
)A 
GROUP BY ID,CASE WHEN NO=0 AND ID<>RANKID THEN RANKID ELSE NO END 
ORDER BY ID 
+0

這不能正常工作。看到這裏:http://sqlfiddle.com/#!6/f473ae/3 –

+0

@ThorstenKettner,你是對的,我們將有空隙後,這個查詢將返回錯誤的結果。 –

+0

@TedoG。甚至以上的答案也會給出錯誤的結果我將很快更新我的帖子。 – Buddi