[MSSQL] Wyliczanie czasu trwania nachodzacych sie zajec

Odpowiedz Nowy wątek
2006-10-25 16:18
0

Mam sobie tabele z wpisami dotyczacymi pewnych spotkan.

table meetings ( 
  [id] int identity(1,1) primary key, 
  MeetingDate datetime, 
  Lasting datetime,  
  ...
)

MeetingDate - data i czas spotkania
Lasting - czas trwania spotkania

Spotkania moga sie nakladac, czyli jedno spotkanie moze zaczynac sie o jakiej porze i trwac np. 6h, a drugie zaczynac sie pol godziny pozniej i trwac 3h, itd.

Pytanie: W jaki sposob obliczyc jaki byl rzeczywisty czas trwania wszystkich spotkan. W powyzszym przypadku powinno wyjsc 6h (bo jedno jest zawarte w drugim).

Licze na jakies pomysly, bo ja na razie na zaden nie wpadlem i tez niewiele wygooglalem.

pozdrawiam
johny


You need to learn how to walk
before you can run

Pozostało 580 znaków

2006-10-25 19:19
0

A w sytuacji, w której masz powiedzmy jedno spotkanie 9-10 a drugie 11-12, to ma liczyć 2 godziny, czy 3 (od poczatku pierwszego, do końca ostatniego)?


Grunt to uziemienie...

Pozostało 580 znaków

2006-10-25 19:23
0

2 godziny niestety...

Powiedzmy, ze jest jedna sala do zajec i jest w niej kilka rownoczesnych. I tu pytanie ile czasu ta 'sala' byla otwarta - w tym stylu liczenie.

Myslalem z tym liczeniem od poczatku pierwszego do ostatniego, ale znowu nie mam pomyslu jak znalezc dziury pomiedzy nimi.

Nawet niespecjalnie mam pomysl jak szukac czegos na google'u...

PS. To nie musi byc szybkie - rekordow branych pod uwage bedzie max rzedu 10000, wiec nawet jak bedzie wolne, to baza sobie da rade. Wazne, zeby liczylo poprawnie.

pozdrawiam
johny


You need to learn how to walk
before you can run

Pozostało 580 znaków

2006-10-26 13:20
0

Przychodzi mi do głowy taka opcja (wolna, ale raczej poprawna) - stworzenie dodatkowej tabeli (tymczasowej), a następnie wykonanie czegoś takiego:
Dla każdego rekordu z tabeli spotkań sprawdzamy, czy w tabeli tymczasowej jest element, który przecina się (całkowicie lub częściowo) z danym rekordem. Jeśli tak, to odpowiednio przesuwamy początek/koniec rekordu w tabeli tymczasowej, by znaleźć sumę (w sensie teoriomnogościowym) tych spotkań. Jeśli takich przecinających się rekordów w tabeli tymczasowej będzie więcej, to łączymy je w jeden.
Następnie z tabeli tymczasowej wyliczamy sumę czasu trwania każdego z tych rekordów.

Jeśli chodzi o implementację - trzebaby napisać procedurę dla bazy danych, w życiu tego nie robiłem, więc nie napiszę, jak to powinno dokładnie wyglądać.

Być może nie jest to idealne rozwiązanie (w sensie optymalizacji), jednak ja nie widzę lepszego.


Grunt to uziemienie...

Pozostało 580 znaków

2006-10-26 13:31
0

Hmm... wlasnie wpadlem na cos podobnego i jestem w trakcie tworzenia :) Chociaz ja mam pomysl bez tabeli tymczasowej. Zobaczymy co wyjdzie :) Dzieki za poswiecony czas [soczek]

pozdrawiam
johny

...

No i napisalem :)

declare MeetingsCursor cursor read_only for 
select meetingdate, meetingdate+lasting from Meetings order by meetingdate, lasting

declare @meetingDate datetime
declare @endDate datetime
declare @startPoint datetime
declare @endPoint datetime
declare @sum datetime
set @sum = convert(datetime, '1900-01-01 00:00:00:000', 21)

open MeetingsCursor
fetch next from MeetingsCursor into @startPoint, @endPoint
fetch next from MeetingsCursor into @meetingDate, @endDate
WHILE (@@fetch_status <> -1)
begin
    if(@@fetch_status <> -2)
    begin
        if ((@startPoint<[email protected]) and (@endPoint >= @meetingDate)) --poczatek zawiera sie w przedziale
        begin
            if(@endDate > @endPoint) -- nie jest zawarte w liczonym okresie
            begin
                set @endPoint = @endDate
            end
        end
        else
        begin
            set @sum = @sum + @[email protected] --dodajemy do wspolnej sumy 
            set @startPoint = @meetingDate          --i ustawiamy poczatek
            set @endPoint = @endDate                --i koniec na nastepny kawalek
        end
    end
    fetch next from MeetingsCursor into @meetingDate, @endDate
end
set @sum = @sum + @[email protected] --dodajemy do wspolnej sumy koncowy zakres
close MeetingsCursor
deallocate MeetingsCursor
select @sum

Na 1000 rekordach trwa to 2s (Athlon XP 2,5GHz), wiec dla mnie bomba :)

Jakby ktos mial jakies uwagi (w szczegolnosci przyspieszajace) to chetnie wyslucham :)

pozdrawiam
johny


You need to learn how to walk
before you can run

Pozostało 580 znaków

2006-10-26 14:14
0

Hmm... Jeśli dobrze zrozumiałem, to wykorzystujesz sortowanie po czasie rozpoczęcia - sprytne :).


Grunt to uziemienie...

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0