Jak stworzyć pętlę generującą nowe daty miesięcy?

0

Witam wszystkich,

Jakiś czas zacząłem przygodę z SQL i staram się rozwijać wiedzę w tym temacie (nie pracuję z SQL na co dzień tylko uczę się go samemu w wolnym czasie).

Czytając jedną z książek o tej tematyce natknąłem się na 'challenge' aby napisać polecenie które wygeneruje pierwsze i ostatnie dni miesięcy od 2010 to 2015 roku.

Pisząc kod wydawało mi się, że udało mi się tego dokonać ale... za każdym razem dostaję tylko jeden wynik (dzień pierwszego miesiąca).

Wygląda to tak jakby funkcja nie chciała się powtórzyć.

Wklejam kod poniżej:


WITH TabelaDynamiczna (Pierwszy, licznik) AS

(SELECT CAST(CAST(YEAR('2010-01-01') AS varchar) + '-' + CAST(MONTH('2010-01-01') AS varchar) + CAST('-01' AS varchar) AS datetime) AS Pierwszy , 1 AS licznik

UNION ALL

SELECT DATEADD(m, 1, Pierwszy), licznik + 1
FROM TabelaDynamiczna
WHERE licznik < DATEDIFF(m,2010-01-01,2015-12-31)) -- wydawało mi się, że dzięki temu funkcja będzie się zapętlać aż do osiągnięcia końcowej daty...
-- Tabela Dynamiczna stworzona

SELECT Pierwszy AS PierwszyDzienMiesiaca, licznik, CAST(DATEDIFF(d, 1, DATEADD(m, 1, Pierwszy)) AS datetime) AS OstatniDzienMiesiaca
FROM TabelaDynamiczna


Niestety, jak pisałem powyżej nie udało się osiągnąć zamierzonego efektu.

Próbowałem potem używać funkcji WHILE/BEGIN/SET/END ale zupełnie nie udało mi się jej wpasować w kod powyżej i SQL Server 2016 nie chciał wykonać operacji.

Czy mógłbym prosić o rozjaśnienie w jaki sposób zmusić bazę danych do wygenerowania kolejnych miesięcy trzymając się w.w schematu?

Pozdrawiam i z góry dziękuję za odpowiedź!

0

Musisz posłużyć się procedurą składowaną i w niej możesz zrobić pętlę.

0

Możesz zrobić to tak:

with a as ( 

	select 1 lp, to_date('2010-01-01') data from dual

), 

b (lp, data) as (

	select lp, data from a

	union all

	select lp+1 lp, data+1 data from b where data+1 < '2016-01-01'

)

select * from b
where 
case  
	when to_char(data,'dd')*1 = 1
		or data = last_day(data) 
	then 1
end = 1 
0
DECLARE @MinDate DATE = '20100101',
        @MaxDate DATE = '20151231';

select 
	x.data pierwszy_dzien,
	eomonth(x.data) ostatni_dzien
from (
SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        data = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate) 
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b) x
where cast(day(x.data) as integer) = 1;

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