2009-10-01 205 views
1

我正在使用一個名爲CELCAT的時間表應用程序,試圖抽出一些關於學生應該被標記爲報告的數據...這似乎是非常困難的,因爲這樣添加和學生登記的結構去除見下文: sql轉向添加日期範圍和刪除日期範圍

studentid eventid  fromdatetime    addition removal 
25149  25145  2009-09-12 10:30:00.000  Y   NULL 
25149  25145  2009-09-12 10:30:00.000  NULL  Y 
25149  25145  2009-09-12 10:30:00.000  Y   NULL 
25150  23013  2009-09-08 09:00:00.000  Y   NULL 
25150  23554  2009-09-07 09:00:00.000  Y   NULL 
25150  25145  2009-09-12 10:30:00.000  Y   NULL 
25150  25145  2009-07-27 00:00:00.000  NULL  Y 
25150  25145  2009-09-12 10:30:00.000  Y   NULL 
25150  25145  2009-09-12 10:30:00.000  NULL  Y 
25150  25145  2009-09-12 10:30:00.000  Y   NULL 
25150  25148  2009-09-12 15:00:00.000  Y   NULL 
25151  25145  2009-09-12 10:30:00.000  Y   NULL 
25151  25145  2009-10-10 00:00:00.000  NULL  Y 
25152  25145  2009-09-19 10:30:00.000  Y   NULL 
25152  25145  2009-07-27 00:00:00.000  NULL  Y 

因此,一個除了學生的手段,他們應該從該日起在寄存器中被標記(寄存器是用自己的周輪廓每週reccurring事件,但我可以處理它的那一面)。刪除將意味着學生不需要在此日期之後被標記,但是可能會在稍後的一週內添加,刪除並重新添加學生。

我想會得到我在正確的方向將是讓結構

studentid eventid fromdate      todate 
25149   25145 2009-09-12 10:30:00.000  2009-09-28 10:30:00.000  
25149   25145 2009-10-13 10:30:00.000  2009-10-24 10:30:00.000 

任何想法如何做到這一點的桌子嗎?還是更好的建議?我想它會涉及一些遊標的使用,除非有人有一個很棒的解決方案。這些表格由CELCAT設計,不能修改。

哦,是它的SQL Server 2005的

通過KM編輯,這裏是一些代碼來測試的解決方案:

DECLARE @YourTable table (studentid int 
         ,eventid int 
         ,fromdatetime datetime 
         ,addition char(1) 
         ,removal char(1) 
         ) 

SET NOCOUNT ON 
INSERT INTO @YourTable VALUES (25149,25145,'2009-09-12 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25149,25145,'2009-09-12 10:30:00.000', NULL,'Y') 
INSERT INTO @YourTable VALUES (25149,25145,'2009-09-12 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25150,23013,'2009-09-08 09:00:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25150,23554,'2009-09-07 09:00:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25150,25145,'2009-09-12 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25150,25145,'2009-07-27 00:00:00.000', NULL,'Y') 
INSERT INTO @YourTable VALUES (25150,25145,'2009-09-12 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25150,25145,'2009-09-12 10:30:00.000', NULL,'Y') 
INSERT INTO @YourTable VALUES (25150,25145,'2009-09-12 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25150,25148,'2009-09-12 15:00:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25151,25145,'2009-09-12 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25151,25145,'2009-10-10 00:00:00.000', NULL,'Y') 
INSERT INTO @YourTable VALUES (25152,25145,'2009-09-19 10:30:00.000','Y' ,NULL) 
INSERT INTO @YourTable VALUES (25152,25145,'2009-07-27 00:00:00.000', NULL,'Y') 
SET NOCOUNT OFF 
+1

如何從給定的樣本數據中獲取這兩個日期範圍行?當您想要的「答案」與給定的樣本數據不匹配時,很難爲您做出查詢。 – 2009-10-01 17:44:22

+0

此表/視圖中是否有另一列表示添加記錄時的時間戳或至少是增量標識符?如果不是這樣,那麼爲ID = 25149的學生設置一個邏輯是相當困難的,因爲他被添加到同一個事件或從同一個事件中移除了3次,但是不清楚先做了什麼。 – van 2009-10-02 15:33:20

+0

如果你指出你希望得到什麼樣的「最終」結果,而不僅僅是「......正確的方向......」,它也會有所幫助。謝謝 – van 2009-10-02 16:10:07

回答

0

一個簡單的方法是創建一個標量函數的studentid和一個eventid返回了一點,表明該學生是否在進入或退出:

create function Event_IsStudentIn(@eventID int, @studentID int) 
returns bit as 
begin 
    declare @in bit 

    set @in = 0 

    select 
    @in = case when addition = 'Y' then 1 else 0 end 
    from [table] 
    where eventid = @eventID and studentid = @studentID 
    order by fromdatetime desc     

    return @in 
end 

但是,在未來,您可能想要調整數據。

+1

我不明白這是如何解決的,也許我沒有足夠好地解答這個問題。 – PeteT 2009-10-01 16:00:01

0

我不確定您正在嘗試獲取的查詢以及日期範圍如何提供幫助。

但是,您可以保留當前表,它就像一個日誌。只需添加一個保持當前狀態的彙總表。插入舊錶並更新新表。你可以查詢新的來判斷IN/OUT並使用舊的進行更詳細的分析。

0

我不太清楚你需要怎樣處理數據,但是這裏是如何將數據轉換成你想要的格式。

SELECT studentid, eventid, fromdatetime as fromdate, 
    (SELECT TOP 1 fromdatetime FROM table 
    WHERE studentid = t1.studentid 
     AND eventid = t1.eventid 
     AND removal = 'Y' AND fromdatetime > t1.fromdatetime 
    ) AS todate 
FROM table t1 
WHERE addition = 'Y' 

這個查詢會產生你要的格式的數據:

studentid eventid fromdate      todate 
25149  25145  2009-09-12 10:30:00.000  2009-09-28 10:30:00.000 
25149  25145  2009-10-13 10:30:00.000  2009-10-24 10:30:00.000 

此查詢可能是低效的大量數據,所以我真的希望你的表有標識列這是索引。如果是,請將AND fromdatetime > t1.fromdatetime替換爲AND id > t1.id。這應該使子查詢更有效率。

+0

我試過這個查詢,它不起作用。我將用表定義編輯原始問題並插入以填充示例數據。從那裏你所要做的就是將兩個「FROM表」替換爲「FROM @YourTable」,並使用原來問題中的代碼。 – 2009-10-02 17:12:44

+0

我看了這個,查詢確實按照我認爲應該的方式工作,但目前的問題是數據。也許我誤解了數據的結構,但在上面的示例數據中,插入後有刪除,同一天有多個插入,同一天插入和刪除。 也許OP可以準確解釋數據代表什麼,以及上面發佈的樣本是實時數據還是樣機。 – Richard 2009-10-03 16:07:22

0

我覺得有一些錯誤的樣本數據 一共有3條記錄

 
25149  25145 2009-09-12 10:30:00.000  Y   NULL 
25149  25145 2009-09-12 10:30:00.000  NULL  Y 
25149  25145 2009-09-12 10:30:00.000  Y   NULL
基本上他們說,加入學生/刪除,並在同一時間再次添加。 但是,請記住,選擇訂單時不能保證。如何知道學生不是先被移除然後再添加兩次? 該問題要求輸出中的行
25149  25145  2009-10-13 10:30:00.000  2009-10-24 10:30:00.000
,但'2009-10-13'值在數據中無處。



然後這三個:

25150  25145 2009-09-12 10:30:00.000  Y    NULL 
25150  25145 2009-07-27 00:00:00.000  NULL   Y 
25150  25145 2009-09-12 10:30:00.000  Y   NULL
正是我上述假設的情景 - 通過日期來看,學生首先被移除,然後添加兩次!