Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在一个窗口中合并重叠时间?_Sql_Sql Server_Sql Server 2008_Tsql - Fatal编程技术网

Sql 如何在一个窗口中合并重叠时间?

Sql 如何在一个窗口中合并重叠时间?,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我有一张这样的桌子: 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')

我有一张这样的桌子:

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,我试图在这个表上做一个
分组,合并时间在前后6小时的窗口内重叠。因此,在上表中,行
1
2
将合并为一行,因为它们包含重叠的时间范围:

John 2012-01-01 06:00:01.000 2012-01-01 18:00:02.000
4
5
将被合并,因为从
07:01:01.000
中减去6小时将进入行
4
的窗口


在一个包含大约一百万行的大表上执行此操作,有没有好方法?

我认为最好的方法是创建一个
windows
表,并将#temp表与这个新的窗口表连接起来:

1) 步骤1,准备具有所有可能窗口间隙的窗口表(包含重叠窗口):

2) 在临时表上创建索引以提高性能

   create index pw_idx on #possible_windows ( Name, start_w)
3) 消除自联接选择中的重叠窗口。这就是创建索引的原因:

   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

请回去做你的性能测试

我想你的短信有错。当你说第1行变成06:00:01.000-18:00:02.000时,不是03:00:01.000-18:00:02.000吗?(09:00-6h=03:00而非06:00)
   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
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