MSSQL wyliczanie ilości dni miesiąca według daty

0

Witam,
Mam problem z poniższym kodem:

select DATA_DO, datediff(day, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)), dateadd(month, 1, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)))) 
  - DATEDIFF(day, (datediff(day, (DATEADD(month, DATEDIFF(month, 0, DATA_DO), 0)), convert(date,DATA_DO)) + 1), 
  datediff(day, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)), dateadd(month, 1, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)))))

DATA_DO to kolumna z typem datetime

Działa prawidłowo dla DATA_DO kiedy jest z obecnego miesiąca, zaś jeśli data jest wyższa niż bieżący miesiąc to ilości dni z DATA_OD jest wyciągana z jak leci tzn. jeśli DATA_DO = 2022-01-10 to bierze ze stycznia właśnie 10 dni

Pomoże ktoś ???

0

ale co to ma w ogóle robić??

0

Na podstawie ilości dni jest potem wyliczana wartość netto, WARTOSC_NETTO = stawka za dzień * ilość dni

jeśli np. DATA_DO = 2021-12-23, a stawka za dzień jest np. 100 to powinniśmy mieć: 23 razy 100 =2300,
jeśli np. DATA_DO = 2022-01-10, a stawka za dzień jest np. 100 to powinniśmy mieć 31 razy 100 = 3100 (tyle dni ma grudzień), a w styczniu powinno policzyć 10 razy 100 = 1000

0

Domyślam się, że w tym CASE są błędy:

SELECT
CASE 
WHEN TYP = 'd' THEN STAWKA * datediff(day, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)), dateadd(month, 1, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)))) 
  - DATEDIFF(day, (datediff(day, (DATEADD(month, DATEDIFF(month, 0, DATA_DO), 0)), convert(date,DATA_DO)) + 1), 
  datediff(day, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)), dateadd(month, 1, dateadd(day, 1-day(convert(date,DATA_DO)), convert(date,DATA_DO)))))
when TYP = 'd' and month(DATA_DO) < month(getdate()) and year(DATA_DO) < year(getdate()) then STAWKA * datediff(day, dateadd(day, 1-day(convert(date,getdate())), convert(date,getdate())), dateadd(month, 1, dateadd(day, 1-day(convert(date,getdate())), convert(date,getdate()))))
WHEN TYP = 'm' THEN STAWKA
END AS WARTOSC_NETTO
FROM TABELA1

gdzie TYP='d' to dzień, zaś TYP='m' to miesiąc

0

ale za jaki okres chcesz tą ilość dni wyliczyć? A najlepiej podaj przykładowe zakresy i co ma być jako wynik

0

Jak sama nazwa kolumny DATA_DO mówi jest to data kiedy kończy się umowa, zatem żeby wyliczyć prawidłowo stawkę za wybrany okres w skali miesiąca zakładając, że stawka jest naliczana dziennie (TYP='d') to musimy przemnożyć ilość dni razy stawkę (ilość dni dla miesiąca w DATA_DO), zaś jeśli stawka jest rozliczana miesięcznie (TYP='m') to WARTOSC_NETTO = STAWKA (przy miesięcznym nic nie mnożymy)

jeśli DATA_DO jest równa np. 2021-12-10 to ilość dni za jakie trzeba przemnożyć stawkę równa jest 10 (przy uruchomieniu w grudniu) - przy uruchomieniu w styczniu ta data nie jest już brana pod uwagę, ta część kodu procedury działa już

jeśli DATA_DO jest równa np. 2022-01-10 to ilość dni za jakie trzeba przemnożyć stawkę równa jest 31 (przy uruchomieniu w grudniu, ponieważ w tym przypadku DATA_DO jest większa niż data uruchomienia procedury, czyli grudzień, musimy przemnożyć pełne 31 dni z grudnia), zaś przy uruchomieniu procedury w styczniu będziemy mieć 10dni do pomnożenia, a w lutym ta data już nie będzie brana pod uwagę

ITD.

Myślę, że opisałem zrozumiale co jest moim oczekiwanym wynikiem

0
select 
  iif(TYP = 'd', 
    datediff(
      day, 
      dateadd(day, 1 - datepart(day, data_usera), data_usera), 
      iif(data_usera < date_do, data_usera, data_do)
    ) * stawka, 
    stawka
  ) as wartosc_netto 
from 
  tabela

Nie wyjaśniłeś za dużo - większości trzeba się domyślać. Piszesz nie na temat - nadal nie wiadomo skąd jest brana data "przy uruchomieniu w grudniu".
W moim zapytaniu datę do której ma wyliczyć stawkę (nie myl z datą DATA_DO - to jest to twoje przykładowe "przy uruchomieniu w grudniu" i "przy uruchomieniu procedury w styczniu" to data_usera. Najprawdopodobniej u ciebie jest tam GETDATE(). Co do odrzucania wyników jeśli DATA_DO jest z wcześniejszego miesiąca / roku to wystarczy wyfiltrować wszystkie rekordy, które mają wartosc_netto < 0

0

DATA uruchomienia to po prostu getdate() uruchamiamy dzisiaj to będzie dzisiejsza data. DATA_DO to kolumna, w której są zapisane daty w bazie danych w TABELA1

0

Tu przecież nie potrzeba, żadnych datediffów, bo tak naprawdę ma znaczenie nie dzienna data na którą liczymy a miesiąc w którym wykonujemy obliczenia

więc w uproszczeniu

select 
    case when typ = 'd' then
         case when data_od < EOMONTH(@data) then
              day(data_od)
         else
              day(EOMONTH(@data))
        end
    else
       1
   end * stawka
from
   tabela
where
--wykluczmy te których nie liczymy
     @data between data_od and EOMONTH(data_do)

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