sql превратить даты добавления и удаления в диапазоны дат - PullRequest
1 голос
/ 01 октября 2009

Я использую приложение хронометража под названием 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 голосов
/ 11 декабря 2009

Я думаю, что с образцами данных что-то не так Первые 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
Именно гипотетический сценарий, который я описал выше - судя по дате, ученик был сначала удален, а затем добавлен дважды!
0 голосов
/ 01 октября 2009

Я не уверен в запросе, который вы пытаетесь получить, и как диапазоны дат помогут.

Однако вы можете сохранить текущую таблицу, это как журнал. Просто добавьте сводную таблицу, которая сохраняет текущее состояние. Вставьте старую таблицу и обновите новую. Вы можете запросить новый, чтобы сказать, если IN / OUT и использовать старый для более подробного анализа.

0 голосов
/ 02 октября 2009

Я не совсем уверен, что вам нужно делать с данными, но вот как получить данные в нужном вам формате.

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 голосов
/ 01 октября 2009

Одним простым способом было бы создать скалярную функцию, которая для студента и четного возвращала бит, указывающий, находится или нет этот студент:

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

Однако в будущем вы можете реструктурировать эти данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...