Jak prawidłowo liczyć i aktualizować liczbę dni roboczych w kalendarzu?

0

Witam,

Od kilku dni męczę się z napisaniem pewnej procedury w T-SQL. Chciałbym zaktualizować dane w Tabela_1, w kolumnie Jan powinno sprawdzić korzystając z danych w Tabela_2 czy pierwszy rekord jest dniem roboczym, jeśli tak to przechodzi do następnego rekordu, jeśli nie to odejmuje 1 dzień od daty z komórki i sprawdza ponownie, jeśli nadal data nie jest dniem roboczym to ponownie odejmuje 1 dzień itd. Gdy data będzie dniem roboczym to po przejściu do następnego rekordu najpierw odejmuje liczbę dni jaką trzeba było odjąć od pierwszej daty a następnie wykonuje się ta procedura co wcześniej ze sprawdzaniem czy nowo powstała data jest dniem roboczym, po przejściu do kolejnego rekordu odejmuje liczbę odjętych dni z pierwszego + drugiego rekordu (jeśli trzeba było coś dodatkowo odjąć) itd. Gdy kolumna Jan zostanie sprawdzona to zmienna pamiętająca liczbę dni do odjęcia się zeruje i te same procedury przechodzą do kolumny Feb itd. Przykład: w kolumnie Jan w pierwszym rekordzie zostaje data 2023-01-11, w drugim rekordzie 2023-01-08 jest dniem wolnym od pracy więc data zostaje zmieniona na 2023-01-05, w trzecim rekordzie na start od daty 2023-01-07 odejmujemy 3 dni bo tyle trzeba było odjąć w poprzednim rekordzie, 2023-01-04 jest dniem roboczym więc idziemy dalej, w czwartym rekordzie 2023-01-07 staje się 2023-01-04 tak jak poprzedni, w piątym rekordzie 2023-01-04 staje się 2023-01-01 co jest dniem wolnym od pracy więc odejmujemy dni by była datą roboczą i powstaje 2023-12-30, w ostatnim rekordzie jest 2023-01-03, odejmujemy od tej daty 5 dni i powstaje 2022-12-29. To zapytanie nie może posiadać wirtualnych tabel

screenshot-20231112155001.png
screenshot-20231112155029.png

1
morking napisał(a):

![screenshot-20231112155001.png]

Strasznie masz to skomplikowane. Możesz opowiedzieć coś więcej tak ludzkim językiem co to za zadania? Na moje oko to tabela transakcja. I nie bardzo rozumiem
Dlaczego ktoś je kiedyś uzupełnił a teraz musisz to zmieniać?
Daty zadań że stycznia 2023 się zmieniły? Pytam, bo jak zrozumiem to może da się coś sensownego zaproponować

Jeśli chodzi o cześć rozwiązania dla Twojego pomysly:
Generalnie, to możesz zrobić update rekordów, które nie są dniami roboczymi.
Czy sprawdzasz datę w tabela1, biorąc z drugiej tylko rekordy dni roboczych.
Jak rekord jest w tabeli, to zostawiasz, jak nie to odejmujesz dzień. Taka procedurę uruchomisz kilka razy i będzie finalnie ok.

Ale to, żeby pamiętać ile finalnie odjales w poprzednim wierszu, to ja za słaby jestem

A teraz z drugiej strony.
Wspomniałem już w pierwszym wątku - kolumny w tabela1 to jest nieporozumienie.
Tam powinny być 2 kolumny: Activity_name i Data. Wyobraź sobie, że za chwilę będziesz chciał start datę i end datę.
A z tego co piszesz, w kolumnie Jan po update będziesz mial datę z grudnia 2022....

Tabela 2 to też delikatnie mówiąc nieefektywność duża. Tam powinna być lista dni wolnych (czyli w Pl kilkanaście dni), a soboty i niedziele zrobiłbyś z numeru dnia tygodnia....
Obie tabele według mnie nie są zrobione zgodnie ze sztuką. Nie wiem ile masz tych danych, ale ja z bazy danych przeszedłbym z tym na Excela, bo wartości dodanej ten serwer sql tu nie wniosi

0

Z biznesowego punktu widzenia chcę osiągnąć kalendarz z czynnościami do wykonania dla klienta. Pracownik podaje w programie datę według, której obliczają się pozostałe daty (do tej części jest już wykonane) i różnice między datami aktywności w styczniu wynikają z czasu jaki na nie potrzeba, dlatego chcę by zawsze te różnice były stałe bo gdy jedna aktywność wypada w niedzielę a druga przed nią w sobotę i trzecia w piątek to będzie zbyt wiele rzeczy do wykonania na jeden dzień gdy przesuniemy wszystkie na piątek. Aktywności w tabeli, na której by działała procedura są już z góry posortowane malejąco, liczba tych aktywności może być zmienna. W każdym miesiącu kolejność wykonania aktywności jest taka sama. Nie ma żadnego problemu jeśli przez odejmowanie dat aktywność z 03.01.2023 zejdzie na 12.2022.

Tabela_2 jest widokiem utworzonym na potrzebę tej procedury, wiem że tabela_1 powinna wyglądać inaczej ale nie mogę tego zmienić.

Generalnie to największy kłopot mam z przechodzeniem po wierszach i pamiętaniem ile odjąć

1
morking napisał(a):

Z biznesowego punktu widzenia chcę osiągnąć kalendarz z czynnościami do wykonania dla klienta. Pracownik podaje w programie datę według, której obliczają się pozostałe daty (do tej części jest już wykonane) i różnice między datami aktywności w styczniu wynikają z czasu jaki na nie potrzeba, dlatego chcę by zawsze te różnice były stałe bo gdy jedna aktywność wypada w niedzielę a druga przed nią w sobotę i trzecia w piątek to będzie zbyt wiele rzeczy do wykonania na jeden dzień gdy przesuniemy wszystkie na piątek. Aktywności w tabeli, na której by działała procedura są już z góry posortowane malejąco, liczba tych aktywności może być zmienna. W każdym miesiącu kolejność wykonania aktywności jest taka sama. Nie ma żadnego problemu jeśli przez odejmowanie dat aktywność z 03.01.2023 zejdzie na 12.2022.

Tabela_2 jest widokiem utworzonym na potrzebę tej procedury, wiem że tabela_1 powinna wyglądać inaczej ale nie mogę tego zmienić.

Generalnie to największy kłopot mam z przechodzeniem po wierszach i pamiętaniem ile odjąć

Ale w tej chwili tak będzie act2 act 3 i act4 - wszystkie wypadną 5 stycznia. Rozumiem że dla klienta robisz to co miesiąc.
Jeśli pracownik podaje te datę to zrób na tym etapie walidacja jeśli poda dzień wolny to musi ja poprawić. Ale zostanie jak rozumiem problem kumulacji/kolejkowania/ lokacji zasobów.
Może powinieneś walidowac jw. Datę wprowadzona przez pracownika, i dodawać dni dla kolejnych aktywności również z walidacja?

0

To działa tak że pracownik podaję datę a mój program na podstawie pewnych wytycznych wszystkie pozostałe oblicza. To jakie aktywności wypadają w który dzień miesiąca jest stałe i się nie zmieni, problem tylko się pojawia jak wypadną w weekend, prosiłbym tylko o pomoc przy kodzie, piszę już tą aplikację dłuuuugi czas i wiem że to jest najlepsze rozwiązanie.

0

Dla ułatwienia zamieszczam schemat blokowy
screenshot-20231113005415.png

0

Nie czytałem szczegółowo założeń, ale jeśli już zajęło ci to kilka dni to może pomyśl o CRL albo kursorach w połączeniu ze zwykłymi if-ami jak w schemacie?
Na pewno wyrobisz się w pół dnia. A elegancko to pewnie funkcje okna.

1

Cały problem polega na tym, ze myślisz jak programista i w głowie masz pętle, nawet schemat blokowy napisałeś. A po "SQLowemu" wystarczy pomyśleć tak: dla zadanej daty weź pierwszy roboczy dzień z tabela2 mniejszy lub równy zadanej dacie. Czyli dla 2023-01-08 będzie to zapytanie:

SELECT TOP 1
     From_Date
From
    Tabela_2
WHERE
  [day type]=1
  and From_Date <= '2023-01-08'
ORDER BY
    From_Date DESC

Mozesz teraz Wykorzystać to w Zapytaniu:

  SELECT
      Activity_Name
      ,Jan
      ,(SELECT TOP 1
           From_Date
      From
        Tabela_2
      WHERE
        [day type]=1
        and From_Date <= tabela_1.Jan
      ORDER BY
          From_Date DESC) [Jan workinh day]
FROM
    Tabela_1

Mało wygodnie, ale możesz to ubrać w funkcje skalarną:

CREATE  FUNCTION [dbo].[getWorkingDayDate](@dt datetime)
RETURNS datetime
AS
BEGIN

DECLARE @result datetime

SELECT TOP 1
     @result = From_Date
From
    Tabela_2
WHERE
  [day type]=1
  and From_Date <= @dt
ORDER BY
    From_Date DESC
RETURN ISNULL(@result,0)
END

i wykorzystać w zapytaniu:

  SELECT
      Activity_Name
      ,Jan
      ,[dbo].[getWorkingDayDate](tabela_1.Jan) [Jan workinh day]
FROM
    Tabela_1
0

Teraz widzę, że nie rozwiazałem problemu, ale nie rozumiem tego:

w czwartym rekordzie 2023-01-07 staje się 2023-01-04 tak jak poprzedni

Dlaczego tak jak poprzedni, a nie 2023-01-05 bo to jest pierwszy dzień roboczy poprzedzający 2023-01-07?

1
Panczo napisał(a):

Teraz widzę, że nie rozwiazałem problemu, ale nie rozumiem tego:

w czwartym rekordzie 2023-01-07 staje się 2023-01-04 tak jak poprzedni

Dlaczego tak jak poprzedni, a nie 2023-01-05 bo to jest pierwszy dzień roboczy poprzedzający 2023-01-07?

2023-01-07 staje się 2023-01-04, dlatego, że 2023-01-08 stał się 2023-01-05 (różnica 3 dni)
:)

ps.
@Panczo: nie mogę jeszcze docenić, ale post wyżej super pomysły!

0

Cięgle mi chodzi to po głowie, jednak nie mogę wpaść jak to rozwiązać zapytaniem.
Wydaję mi się, że dużo prościej by było to zrobić już na etapie tworzenia tych dat wcześniejszych etapów.
Pytanie jak przechowujesz info ile dni wcześniej ma być zrobiony poprzedni etap?

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