我有一个汇总数据表,用于存储每日计数,每月计数和年度计数的数据。
“rollup_type”指定每日(1)/每月(2)/年数据(3)。对于年度记录,monthl / daily均为null。对于月度记录,每日为空。
我正在尝试根据输入开始日期和结束日期进行简单的SELECT,但没有成功。以下是我尝试过的无法正常工作的内容。
declare @start_date datetime = '2013-02-01'
declare @enddate datetime = '2014-01-12'
select * from olr_rollup_data rd
where ( rd.Year > DATEPART(YYYY, @start_date) or ( rd.Year = DATEPART(YYYY, @start_date) and ( (rd.Month > DATEPART(MM, @start_date) and rd.day is null) or (rd.MONTH = DATEPART(MM, @start_date) and rd.day >= DATEPART(DD, @start_date) ))))
and ( rd.Year < DATEPART(YYYY, @enddate) or ( rd.Year = DATEPART(YYYY, @enddate) and ( (rd.Month < DATEPART(MM, @enddate) and rd.day is null) or ( rd.MONTH = DATEPART(MM, @enddate) and rd.Day <= DATEPART(DD, @enddate) ))))
基本上,通用选择语句将使用输入日期的每日,每月和每年数据的组合。它应该选择天数加上整月,输入日期涵盖两个月之间等等。
如果您帮助找出正确的选择陈述,我将不胜感激。谢谢。
答案 0 :(得分:0)
日期总是令人痛苦,这就是为什么在可用时使用内置日期时间功能很好。可悲的是,这不会起作用,我们必须弄清楚一些技巧。
使用日期作为“数字”的一种方法是将年份乘以10000,将月份乘以100并将这些数字添加到月份的日期。这将给出一个整数,其中数字看起来像这样
YYYYMMDD
虽然脱节(有很多整数你永远不会看到),但是这个表示的任何整数都与它所代表的日期具有相同的基数(日期越大,整数也越大。)
我们可以使用它来解决您的问题,如下所示:
DECLARE @startDate INTEGER = 20130201
DECLARE @endDate INTEGER = 20140112
SELECT *
FROM
(
SELECT ((year*10000)+(ISNULL(month,0)*100)+ISNULL(day,0)) as dateInt, *
FROM olr_rollup_date
) sub
WHERE dateInt >= @startDate AND dateInt <= @endDate
这将包括“已包围”的月份的汇总行。由于我们将空值默认为0,因此2014年5月的空值为20140500.这比4月份的任何日期都要大,且比6月份的任何日期都要小,但小于5月的任何日期。
年将以类似的方式运作。