背景:很多的统计报表中需要输入起始,结束日期来按照不同的时间单位查询数据,而且显示出来的列名是你的动态时间单位。你的表数据是按天存的日期,那么这时候你可能要做一些sql函数或者存储过程来实现了。
1.根据起始和结束日期来获取范围中的每一天,作为结果集返回(函数)
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')
结果展示:
2.根据起始和结束日期来获取范围中的每周(包括当周起始和结束日期),作为结果集返回(存储过程)
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'
结果展示:
3.根据起始和结束日期来获取范围中的每月,作为结果集返回(存储过程)
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'
结果展示:
4.根据起始和结束日期来获取范围中的每年,作为结果集返回(存储过程)
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'
结果展示:
应该还要好的方法。望各位大佬不吝赐教