sql将添加和删除的日期转换为日期范围

时间:2009-10-01 15:35:08

标签: sql sql-server sql-server-2005 tsql

我正在使用一个名为CELCAT的时间表应用程序并尝试提取一些关于学生何时应该被标记为报告的数据......这似乎非常困难,因为在寄存器上添加和删除学生的方式是结构化的见下文:

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

因此,添加学生意味着他们应该从注册日期开始标记(寄存器是每周重复发生的事件,有他们自己的周简介,我可以处理它的那一面)。删除意味着学生不需要在此日期之后被标记,但学生可能会被添加,删除,然后在下周重新添加。

我认为让我朝着正确的方向前进的方法是获得一张结构表

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

4 个答案:

答案 0 :(得分: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 :(得分:0)

我不确定您要获取的查询以及日期范围将如何帮助。

但是,您可以保留当前表,它就像一个日志。只需添加一个保持当前状态的汇总表。插入旧表并更新新表。您可以查询新的IN / OUT并使用旧的进行更详细的分析。

答案 2 :(得分: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。这应该使子查询更有效。

答案 3 :(得分: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
正是我上面描述的假设场景 - 从日期判断,学生先被删除然后再加两次!