我正在使用一个名为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
答案 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正是我上面描述的假设场景 - 从日期判断,学生先被删除然后再加两次!