2012-05-12 10 views
4

私はこのようなテーブルがあります。ウィンドウ内で重複する時間をマージするにはどうすればよいですか?

CREATE TABLE #TEMP (Name VARCHAR(255), START_TIME datetime, END_TIME datetime); 

INSERT INTO #TEMP VALUES('John', '2012-01-01 09:00:01', '2012-01-01 12:00:02') 
INSERT INTO #TEMP VALUES('John', '2012-01-01 09:40:01', '2012-01-01 11:00:02') 
INSERT INTO #TEMP VALUES('John', '2012-01-02 05:00:01', '2012-01-02 05:15:02') 
INSERT INTO #TEMP VALUES('David', '2012-01-04 05:00:01', '2012-01-04 05:15:02') 
INSERT INTO #TEMP VALUES('David', '2012-01-05 07:01:01', '2012-01-05 15:15:02') 

SELECT * 
FROM #TEMP 

DROP TABLE #TEMP 

を、データがある:数を考えると

 Name START_TIME     END_TIME 
1 John 2012-01-01 09:00:01.000 2012-01-01 12:00:02.000 
2 John 2012-01-01 09:40:01.000 2012-01-01 11:00:02.000 
3 John 2012-01-02 05:00:01.000 2012-01-02 05:15:02.000 
4 David 2012-01-04 05:00:01.000 2012-01-04 05:15:02.000 
5 David 2012-01-05 07:01:01.000 2012-01-05 08:15:02.000 

は6、言って、私はこのテーブルの上にGROUP BYを行うと、時間にその重複をマージしようとしています前と後の6時間の窓の中で。 07:01:01.000から6時間を差し引くことのウィンドウに落ちるため

John 2012-01-01 06:00:01.000 2012-01-01 18:00:02.000 

45がマージされます。これらは重複する時間範囲を含むしたがって、上記の表では、行12は、単一の行にマージされます行4

約100万行の大きなテーブルでこれを行う良い方法はありますか?

+0

あなたはアンカーテキストに間違いがあると思います。行1が06:00:01.000 - 18:00:02.000になると言うとき、03:00:01.000 - 18:00:02.000? (09:00 - 6h = 03:00で06:00ではない) – danihp

答えて

2

私はこれを行うための最善の方法は、windowsテーブルを作成し、この新しいウィンドウテーブルで#TEMPテーブルを結合していることを考える:

1)ステップ1、すべての可能な窓の隙間にウィンドウテーブルの作成には、(窓をoverlaping含まれています):

SELECT 
     Name, 
     dateadd(hour, -6, start_time) as start_w, 
     dateadd(hour, +6, start_time) as end_w 
    into #possible_windows 
    FROM #TEMP 

2)は、パフォーマンスを向上させるために一時テーブルにインデックスを作成します

create index pw_idx on #possible_windows (Name, start_w) 

3)自己中overlaping窓がSELEに参加排除ct。

select p2.* 
    into #myWindows 
    from #possible_windows p1 
    right outer join #possible_windows p2 
    on p1.name = p2.name and 
     p2.start_w > p1.start_W and p2.start_w <= p1.end_w 
    where p1.name is null 

4)#myWindowsを使用して、テーブルに参加したり、直接それを使用する:これは、インデックスを作成する理由です。

WORKING:

SELECT 
    Name, 
    dateadd(hour, -6, start_time) as start_w, 
    dateadd(hour, +6, start_time) as end_w, 
    ROW_NUMBER() over(partition by Name order by Name, 
        dateadd(hour, -6, start_time)) as rn 
into #possible_windows 
FROM #TEMP 

create index pw_idx on #possible_windows (Name, start_w) 

select p2.* 
from #possible_windows p1 
right outer join #possible_windows p2 
    on p1.name = p2.name and 
    p2.start_w > p1.start_W and p2.start_w <= p1.end_w 
where p1.name is null 

結果:

Name start_w  end_w   rn 
----- ------------- ------------- -- 
David 2012-01-03 23:00:012012-01-04 11:00:011 
David 2012-01-05 01:01:012012-01-05 13:01:012 
John 2012-01-01 03:00:012012-01-01 15:00:011 
John 2012-01-01 23:00:012012-01-02 11:00:013 

PE:、あなたのパフォーマンステストに戻ってください!

関連する問題