Get every day, week, month and year according to the start and end date of sql statement

Background: in many statistical reports, you need to enter start and end dates to query data according to different time units, and the displayed column names are your dynamic time units. Your table data is saved by the day, so you may need to do some sql functions or stored procedures to implement it.

1. Get each day in the range according to the start and end dates, and return as the result set (function)

create function [dbo].[fn_GetDateRange](@DATE_START datetime, @DATE_END datetime)
RETURNS TABLE
AS
RETURN
(
SELECT convert(char(10), DATEADD(dd, number, @DATE_START),120) AS DATA_DATE 
FROM    master.dbo.spt_values  as spt
WHERE   type = 'p' AND number <= DATEDIFF(DAY, @DATE_START, @DATE_END)
)

GO
select * from  fn_GetDateRange('2018-07-31','2018-08-10')

Results:

2. Get the week in the range (including the start and end dates of the current week) according to the start and end dates, and return it as the result set (stored procedure)

CREATE PROCEDURE [dbo].[GetWeekRange]
@tmpDate datetime, @DATE_END datetime
AS
BEGIN
	SET DATEFIRST 1
   DECLARE @index INT
   DECLARE @table TABLE
    (
      WeekTimes INT ,
      FirstDay datetime ,
      EndDay datetime
    )
   DECLARE @YearFistWK INT
   SET @YearFistWK= DATEPART(dw, @tmpDate)
   SET @index = ( SELECT   DATEPART(WEEK, @tmpDate))
   IF ( @YearFistWK = 7 )
    BEGIN 
        SET @index = @index + 1
    END
WHILE @tmpDate <= @DATE_END
    BEGIN
        INSERT  INTO @table
                SELECT  @index ,
                        a.FirstDay ,
                        b.EndDay
                FROM    ( SELECT    1 AS ID ,
                                    DATEADD(wk, DATEDIFF(wk, 0, @tmpDate), 0) AS FirstDAy
                        ) a
                        LEFT JOIN ( SELECT  1 AS ID ,
                                            DATEADD(wk,
                                                    DATEDIFF(wk, 0, @tmpDate),
                                                    6) AS EndDay
                                  ) b ON a.ID = b.ID
 
        SET @tmpDate = DATEADD(DAY, 7, @tmpDate)
        SET @index = @index + 1
		END
		SELECT  WeekTimes, CONVERT(varchar(100), FirstDay, 23) FirstDay,CONVERT(varchar(100), EndDay, 23) EndDay
FROM    @table
END

GO
exec GetWeekRange '2018-07-31','2018-08-10'

Results:

3. Get the months in the range according to the start and end dates, and return as the result set (stored procedure)

CREATE PROCEDURE [dbo].[GetMonthRange] 
@tmpDate datetime, @DATE_END datetime
AS
BEGIN
	DECLARE @table TABLE
    (
	  DateMonth datetime
	)
	WHILE @tmpDate <= @DATE_END
	BEGIN
        INSERT  INTO @table
                SELECT  DATEADD(mm, DATEDIFF(mm, 0, @tmpDate), 0) AS DateMonth
                      
        SET @tmpDate = CONVERT(varchar(7), DATEADD(mm, 1, @tmpDate) , 120) + '-01'
		END
		select CONVERT(varchar(7), DateMonth, 23) DateMonth  from @table
END

GO
exec GetMonthRange '2018-07-31','2018-08-10'

Results:

4. Get the year in the range according to the start and end dates, and return as the result set (stored procedure)

CREATE PROCEDURE [dbo].[GetYearRange] 
@tmpDate datetime, @DATE_END datetime
AS
BEGIN
DECLARE @table TABLE
    (
	  DateYear datetime
	)
	WHILE @tmpDate <= @DATE_END
	BEGIN
        INSERT  INTO @table
                SELECT  DATEADD(yy, DATEDIFF(yy, 0, @tmpDate), 0) AS DateYear
                      
        SET @tmpDate = CONVERT(varchar(4), DATEADD(yy, 1, @tmpDate) , 120) + '-01-01'
		END
		select CONVERT(varchar(4), DateYear, 23) DateYear  from @table
END

GO
exec GetYearRange '2017-08-31','2018-08-10'

Results:

 

There should be better ways. I hope you guys will give me some advice

 

Keywords: Stored Procedure SQL

Added by n1tr0b on Fri, 03 Jan 2020 18:40:00 +0200