2011-03-25 40 views
2

我有一個包含一些時間跨度(兩個TIME列)的表如何找出如果時間是在SQL Server序列2008

如:

TimeBegin  TimeEnd 
---------------- ---------------- 
00:00:00.0000000 01:00:00.0000000 
01:00:00.0000000 02:00:00.0000000 
01:30:00.0000000 03:00:00.0000000 

我要弄清楚是否有時間跨度形成一個序列(在上述情況下從00.00 - 03.00)。一些時間跨度可能會重疊,如上例所示。

編輯 我伸出我的表:

WeekDay  TimeBegin  TimeEnd 
----------- ---------------- ---------------- 
3   00:00:00.0000000 01:00:00.0000000 
3   01:00:00.0000000 02:00:00.0000000 
3   02:30:00.0000000 04:00:00.0000000 

和使用的查詢:

;with sequenced as (
    select *,rn=ROW_NUMBER() over (order by timebegin) 
    from tbl 
    where weekday(timebegin) = 2) 
select * 
from sequenced a 
join sequenced b on a.rn=b.rn-1 
where a.TimeEnd < b.TimeBegin 

,但它說,'工作日」是無法識別的內置函數名稱。 「

,所以我把它改爲:

;with sequenced as (
    select *,rn=ROW_NUMBER() over (order by timebegin) 
    from tbl 
    where weekday = 2) 
select * 
from sequenced a 
join sequenced b on a.rn=b.rn-1 
where a.TimeEnd < b.TimeBegin 

但後來它返回一個包含

WeekDay TimeBegin TimeEnd 
3  01:00:00.0000000 02:00:00.0000000 

這實際上是該序列中的行?

感謝 托馬斯

+3

以及預期輸出是什麼?只是一個「是的 - 這是一個序列」或什麼?應該列出造成衝突的行嗎?或那些整齊地形成一個序列?你需要更具體一點! – 2011-03-25 22:09:32

+0

嗨marc_s。對於那個很抱歉。整個序列只需要真或假。謝謝 – ThomasD 2011-03-25 22:21:27

+0

我強烈建議你發現一個ORM。如果我爲程序員建立了監獄,我會迫使他們編寫複雜的TSQL來折磨他們。 – 2011-03-25 23:31:23

回答

0

這將檢查在時間順序表中的所有單記錄,並顯示所有的空白。如果沒有顯示的記錄,那麼你有沒有間隙==數據形成完整的順序

;with sequenced as (
    select *,rn=ROW_NUMBER() over (order by timebegin) from tbl) 
select * 
from sequenced a 
join sequenced b on a.rn=b.rn-1 
where a.TimeEnd < b.TimeBegin 

假設這是一個時間表(只用了一週的數據),你只需要一個特定的一天之內檢查,你可以使用

;with sequenced as (
    select *,rn=ROW_NUMBER() over (order by timebegin) 
    from tbl 
    where weekday(timebegin) = 2) 
select * 
from sequenced a 
join sequenced b on a.rn=b.rn-1 
where a.TimeEnd < b.TimeBegin 

但是begin on weekday 2 (Monday)任何時間跨度跨午夜不認爲它僅覆蓋記錄。

如果這包括多周,並且您需要檢查每個星期一,則會變得更加複雜。

;with sequenced as (
    select *, 
      Date = DateDiff(d,0,timebegin), 
      rn = ROW_NUMBER() over (order by timebegin) 
    from tbl 
    where weekday(timebegin) = 2) 
select * 
from sequenced a 
join sequenced b on a.rn = b.rn-1 and a.Date = b.Date 
where a.TimeEnd < b.TimeBegin 
+2

請注意,這假定行是按順序排列的,即行'i'的'TimeBegin'總是小於'i + 1行''TimeBegin'' – vlad 2011-03-25 22:26:04

+0

Hi Richard,它的工作原理 - 謝謝!這是訂單的問題,因爲時間開始的查詢命令,我想它會照顧訂購問題?如果我需要用額外的列擴展表(例如weekday作爲int),並且我希望在where子句中使用額外的列,那麼我會做一些類似a.WeekDay = 1的事情,還是必須同時包含這兩個列a.WeekDay = 1和b.WeekDay = 1?謝謝,Thomas – ThomasD 2011-03-25 22:39:01

+0

@user它真的取決於你的where子句是否需要在檢測序列之後完成,或者BEFORE。它通常應該進入子查詢 – RichardTheKiwi 2011-03-25 22:59:13

1

,因爲你只需要truefalse整個序列,就可以按照這個算法:

1. sort the sequence in order of TimeBegin 
2. put them in a temp table, include row_number 
3. for every row starting with the second one: 
    check if TimeBegin is smaller than or equal to the TimeEnd for the previous row 
     if no, return false 
4. return true 

編輯:剛剛意識到這種失敗在一些奇怪的情況是這樣的:

TimeBegin  TimeEnd 
---------------- ---------------- 
00:00:00.0000000 05:00:00.0000000 
01:00:00.0000000 02:00:00.0000000 
02:30:00.0000000 03:00:00.0000000 

這應該仍算作一個序列(我認爲)並返回true,但我的算法沒有考慮到這種情況。爲了解決這個問題,當插入臨時表時,刪除前一記錄中完全「包含」的記錄(即如果TimeBegin[i] > TimeBegin[i-1] and TimeEnd[i] < TimeEnd[i-1]

相關問題