Reputation: 6508
I want to get all dates by declaring month and year in SQL server.
Can anyone please share easy lines of SQL code to get it.
For example:
DECLARE @month AS INT = 5
DECLARE @Year AS INT = 2016
SELECT * from Something
I have tried below things,
DECLARE @month TINYINT=5
;WITH CTE_Days AS (
SELECT DATEADD(
MONTH,
@month,
DATEADD(
MONTH,
-MONTH(GETDATE()),
DATEADD(
DAY,
-DAY(GETDATE()) + 1,
CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
)
)
) Dates
UNION ALL
SELECT DATEADD(DAY, 1, Dates)
FROM CTE_Days
WHERE Dates < DATEADD(
DAY,
-1,
DATEADD(
MONTH,
1,
DATEADD(
MONTH,
@month,
DATEADD(
MONTH,
-MONTH(GETDATE()),
DATEADD(
DAY,
-DAY(GETDATE()) + 1,
CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
)
)
)
)
)
)
SELECT Dates
FROM CTE_Days
But I am looking for easy solution with less lines and short answer
Upvotes: 17
Views: 71372
Reputation: 1
Use generate_series. For example:
SELECT * FROM generate_series('2012-10-01':: date,'2012-10-31','1 day');
Upvotes: 0
Reputation: 1
I think the easier way to do that is something like this.
Declare @date datetime ='20240301'
SELECT CONVERT(DATE, right('0'+convert(varchar,dia),2) +'/'+Right('0'+convert(varchar,Month(@date)),2)+'/'+convert(varchar,year(@date)),103)
FROM (select value as dia from String_split('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,',',')) T0
WHERE T0.dia <= day(EOMONTH(@date))
and isnull(dia,'')!=''
Upvotes: 0
Reputation: 2504
A date list table won't take up my storage, will be more efficient than regularly run queries/functions and can be utilised elsewhere.
Create table and populate with all the dates you will need for the application's lifetime:
CREATE TABLE [dbo].[DateTable](
[Date] [smalldatetime] NOT NULL PRIMARY KEY
, [Year] as year([Date]) PERSISTED NOT NULL
, [Month] as month([Date]) PERSISTED NOT NULL
, [Day] as day([Date]) PERSISTED NOT NULL);
Populate the table:
WITH DT
AS
(
SELECT CAST('20000101' as datetime) AS [date]
UNION ALL
SELECT DATEADD(dd, 1, [date])
FROM DT
WHERE DATEADD(dd, 1, [date]) <= '20501231'
)
INSERT INTO DateTable
SELECT [date] FROM DT
OPTION (MAXRECURSION 0);
Non-Clustered Index:
CREATE NONCLUSTERED INDEX [IX_DateTable_Year_Month_inc_Date] ON [dbo].[DateTable]
(
[Year] ASC,
[Month] ASC
)
INCLUDE([Date])
Use will be simple and efficient from the non-clustered index:
select [Date]
from DateTable
where [Year] = @year and [Month] = @Month
Upvotes: 0
Reputation: 1
-- Another simple version:
DECLARE @ADate DATETIME = '2022-03-01'
DECLARE @Numberofdays INT = (SELECT DAY(EOMONTH(@ADate))) , @i int = 0
while @i < @Numberofdays begin print CONVERT(varchar(8), dateadd(day, @i, @ADate ), 112) set @i= @i+1 end
Upvotes: -1
Reputation: 331
This is a other ways but same results.
declare @year int=2021,@month int=3
select DATEADD(dd,a.n-1,datefromparts(@year,@month,1))
from (
select top 31 ROW_NUMBER() over (order by a.object_id) as n
from sys.all_objects a
) a where DATEPART(mm,DATEADD(dd,a.n-1,datefromparts(@year,@month,1)))=3
Upvotes: 1
Reputation: 1
CREATE FUNCTION fn_GetMonthlyDates
(
@ProcessDate smalldatetime
)
RETURNS @LOAN TABLE
(
ProcessDate smalldatetime
)
AS
BEGIN
DECLARE
@Today DATE= @ProcessDate,
@StartOfMonth DATE ,
@EndOfMonth DATE;
DECLARE @DateList TABLE (DateLabel VARCHAR(10) );
SET @EndOfMonth = EOMONTH(@Today);
SET @StartOfMonth = DATEFROMPARTS(YEAR(@Today), MONTH(@Today), 1);
WHILE @StartOfMonth <= @EndOfMonth
BEGIN
INSERT INTO @DateList
VALUES (@StartOfMonth );
SET @StartOfMonth = DATEADD(DAY, 1, @StartOfMonth);
END;
INSERT INTO @LOAN(ProcessDate)
SELECT DateLabel
FROM @DateList;
RETURN
END
Upvotes: 0
Reputation: 1
Here is a query:
DECLARE @ReportDate VARCHAR(20)='2019-02-10'
DECLARE @LastDay INT =DAY(EOMONTH(@ReportDate))
DECLARE @DayStart INT=01
CREATE TABLE #TEMPMonth ([MDay] VARCHAR(20))
WHILE @LastDay>=@DayStart
BEGIN
INSERT INTO #TEMPMonth
SELECT CAST(CAST(YEAR(@ReportDate)AS VARCHAR)+'-'+CAST(MONTH(@ReportDate)AS VARCHAR)+'-'+CAST(@DayStart AS VARCHAR) AS DATE)
SET @DayStart+=1
END
SELECT * FROM #TEMPMonth
DROP TABLE #TEMPMonth
Upvotes: 0
Reputation: 27
Little modification. Query given by @t-clausen.dk will give you correct result only if you ran it on first of the month. With little change this works awesome.
DECLARE @date DATE = getdate()
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a)
SELECT top(day(EOMONTH(@date)))
N day,
DATEFROMPARTS(year(@date),month(@date), n) date
FROM tally
BTW nice trick t-clausen.dk. I couldn't think of more easy way
Upvotes: 0
Reputation: 317
Another CTE based version
DECLARE @Month INT = 2, @Year INT = 2019
;WITH MonthDays_CTE(DayNum)
AS
(
SELECT DATEFROMPARTS(@Year, @Month, 1) AS DayNum
UNION ALL
SELECT DATEADD(DAY, 1, DayNum)
FROM MonthDays_CTE
WHERE DayNum < EOMONTH(DATEFROMPARTS(@Year, @Month, 1))
)
SELECT *
FROM MonthDays_CTE
Upvotes: 3
Reputation: 21
WHERE Dates LIKE '2018-12%'
In a datetime or timestamp it goes Year-Month, so this would pull everything that matches 2018 in December. You can mod this to use your variables as well.
@month = 12;
@year = 2018;
@searchQuery = @year + @month + '%';
WHERE Dates LIKE @searchQuery
Upvotes: 0
Reputation: 5643
You can get all the dates of a month using the following query.
declare @month int, @year int
set @month = 2
set @year = 2008
SELECT
CAST(CAST(@year AS VARCHAR) + '-' + CAST(@Month AS VARCHAR) + '-01' AS DATETIME) + Number
FROM master..spt_values
WHERE type = 'P'
AND
(CAST(CAST(@year AS VARCHAR) + '-' + CAST(@Month AS VARCHAR) + '-01' AS DATETIME) + Number )
<
DATEADD(mm,1,CAST(CAST(@year AS VARCHAR) + '-' + CAST(@Month AS VARCHAR) + '-01' AS DATETIME) )
Hope this will help you.
Upvotes: 1
Reputation: 381
DECLARE @Today DATE= GETDATE() ,
@StartOfMonth DATE ,
@EndOfMonth DATE;
DECLARE @DateList TABLE ( DateLabel VARCHAR(10) );
SET @EndOfMonth = EOMONTH(GETDATE());
SET @StartOfMonth = DATEFROMPARTS(YEAR(@Today), MONTH(@Today), 1);
WHILE @StartOfMonth <= @EndOfMonth
BEGIN
INSERT INTO @DateList
VALUES ( @StartOfMonth );
SET @StartOfMonth = DATEADD(DAY, 1, @StartOfMonth);
END;
SELECT DateLabel
FROM @DateList;
Upvotes: 0
Reputation: 191
DECLARE @MonthNo TINYINT = 03 -- set your month
,@WOYEAR SMALLINT = 2018; -- set your year
IF OBJECT_ID('TEMPDB..#TMP') IS NOT NULL
DROP TABLE #TMP
DECLARE @START_DATE DATETIME
,@END_DATE DATETIME
,@CUR_DATE DATETIME
SET @START_DATE = DATEADD(month, @MonthNo - 1, DATEADD(year, @WOYEAR - 1900, 0))
SET @END_DATE = DATEADD(day, - 1, DATEADD(month, @MonthNo, DATEADD(year, @WOYEAR - 1900, 0)))
SET @CUR_DATE = @START_DATE
CREATE TABLE #TMP (
WEEKDAY VARCHAR(10)
,DATE INT
,MONTH VARCHAR(10)
,YEAR INT
,dates VARCHAR(25)
)
WHILE @CUR_DATE <= @END_DATE
BEGIN
INSERT INTO #TMP
SELECT DATENAME(DW, @CUR_DATE)
,DATEPART(DAY, @CUR_DATE)
,DATENAME(MONTH, @CUR_DATE)
,DATEPART(YEAR, @CUR_DATE)
,REPLACE(CONVERT(VARCHAR(9), @CUR_DATE, 6), ' ', '-')
SET @CUR_DATE = DATEADD(DD, 1, @CUR_DATE)
END
SELECT *
FROM #TMP
Upvotes: 0
Reputation: 561
Same approach as t-clausen, but a more compact:
Declare @year int = 2017, @month int = 11;
WITH numbers
as
(
Select 1 as value
UNion ALL
Select value + 1 from numbers
where value + 1 <= Day(EOMONTH(datefromparts(@year,@month,1)))
)
SELECT datefromparts(@year,@month,numbers.value) Datum FROM numbers
Upvotes: 15
Reputation: 44326
You can't get all days just by declaring the month, you need to add the year as well because of leap years:
DECLARE @date DATE = getdate()
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a)
SELECT top(day(EOMONTH(@date)))
N day,
dateadd(d,N-1, @date) date
FROM tally
Another different solution(by t@clausen):
DECLARE @month AS INT = 5
DECLARE @Year AS INT = 2016
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a)
SELECT N day,datefromparts(@year,@month,N) date FROM tally
WHERE N <= day(EOMONTH(datefromparts(@year,@month,1)))
Upvotes: 12
Reputation: 1270091
If you have a date/time column, then use the month()
function:
select t.*
from t
where month(datecol) = 5;
Upvotes: 2