T-SQL:将时间顺序数据表连接到自身

时间:2015-09-07 13:29:30

标签: sql tsql

我有一个SQL表,其中显示了在系统中运行的几个不同周期的开始时间和结束时间。下表是我正在处理的数据的简化示例。

Batch# Event# Event  Timestamp
1      1      Start  2015-07-01 12:31:31.000
1      2      Start  2015-07-01 12:31:31.000
1      3      Start  2015-07-01 12:31:31.000
1      4      End    2015-07-01 12:33:32.000
1      5      End    2015-07-01 12:33:32.000
1      6      End    2015-07-01 12:33:32.000
2      1      Start  2015-07-01 12:35:32.000
2      2      End    2015-07-01 12:36:32.000

我想制作一个看起来像这样的表。

Batch# Event# Event Timestamp                 Event# Event Timestamp
1      1      Start  2015-07-01 12:31:31.000  4      End    2015-07-01 12:33:32.000
1      2      Start  2015-07-01 12:31:31.000  5      End    2015-07-01 12:33:32.000
1      3      Start  2015-07-01 12:31:31.000  6      End    2015-07-01 12:33:32.000
2      1      Start  2015-07-01 12:35:32.000  2      End    2015-07-01 12:36:32.000

我尝试过使用左外连接,但我得到额外的行。

SELECT *
FROM Table1 as T1
LEFT OUTER JOIN Table1 as T2
ON T1.Batch_no = T2.Batch_no
WHERE T1.Event = 'Start'
      AND T2.Event = 'End'


Batch# Event# Event Timestamp                 Event# Event Timestamp
1      1      Start  2015-07-01 12:31:31.000  1      4      End    2015-07-01 12:33:32.000
1      1      Start  2015-07-01 12:31:31.000  1      5      End    2015-07-01 12:33:32.000
1      1      Start  2015-07-01 12:31:31.000  1      6      End    2015-07-01 12:33:32.000
1      2      Start  2015-07-01 12:31:31.000  1      4      End    2015-07-01 12:33:32.000
1      2      Start  2015-07-01 12:31:31.000  1      5      End    2015-07-01 12:33:32.000
1      2      Start  2015-07-01 12:31:31.000  1      6      End    2015-07-01 12:33:32.000
1      3      Start  2015-07-01 12:31:31.000  1      4      End    2015-07-01 12:33:32.000
1      3      Start  2015-07-01 12:31:31.000  1      5      End    2015-07-01 12:33:32.000
1      3      Start  2015-07-01 12:31:31.000  1      6      End    2015-07-01 12:33:32.000
2      1      Start  2015-07-01 12:35:32.000  2      2      End    2015-07-01 12:36:32.000

2 个答案:

答案 0 :(得分:1)

一种方法:

您可以使用row_number()对每个分区中的行进行编号,一次用于开始,一次用于结束,然后进行连接。

with 
cte_start as (
  select 
    *, 
    r_start = row_number() over (partition by [batch#] order by [event#]) 
  from t where [event] = 'Start'),
cte_end   as (
    select 
      *, 
      r_end = row_number() over (partition by [batch#] order by [event#]) 
    from t where [event] = 'End')

select 
    s.[Batch#], s.[Event#], s.[Event], s.[Timestamp], 
                e.[Event#], e.[Event], e.[Timestamp] 
from cte_start s
join cte_end   e on s.Batch# = e.Batch# and s.r_start = e.r_end

Sample SQl Fiddle

示例结果:

| Batch# | Event# | Event |              Timestamp | Event# | Event |              Timestamp |
|--------|--------|-------|------------------------|--------|-------|------------------------|
|      1 |      1 | Start | July, 01 2015 12:31:31 |      4 | End   | July, 01 2015 12:33:32 |
|      1 |      2 | Start | July, 01 2015 12:31:31 |      5 | End   | July, 01 2015 12:33:32 |
|      1 |      3 | Start | July, 01 2015 12:31:31 |      6 | End   | July, 01 2015 12:33:32 |
|      2 |      1 | Start | July, 01 2015 12:35:32 |      2 | End   | July, 01 2015 12:36:32 |

答案 1 :(得分:0)

这应该可以正常工作。如果需要任何调整,请告诉我。

SQL Server 2008及以上版本

public Frame() { ... }