嗨:在MSSQL / TSQL中的情况如下:让我们说今天的日期是'2016-01-15'(2016年1月15日)。我想搜索数据+ - 30天,但过去10年。因此,搜索范围将是:12月15日到2月15日,但不是仅仅搜索上述日期的+ -30天(2015年12月15日至2016年2月15日),我想仅在12月15日之间搜索所有数据和过去10年的2月15日。
为了正确看待,我正在寻找天气模式,因此我需要在过去的n年中坚持每年接近相同的时间框架。
答案 0 :(得分:0)
这样的事情可以解决问题:
;WITH CTE1(StartDate,EndDate) AS
(
SELECT
DATEADD(MONTH,-1,'2016-01-15') AS startDate
, DATEADD(MONTH,1,'2016-01-15') AS EndDate
UNION ALL
SELECT
DATEADD(YEAR,-1,startDate)
, DATEADD(YEAR,-1,EndDate)
FROM CTE1
WHERE CTE1.StartDate > DATEADD(YEAR,-9,'2016-01-15')
), CTE2 AS (
SELECT DISTINCT columnIDs
FROM table t
INNER JOIN cte1 c ON t.date BETWEEN c.StartDate and c.EndDate
)
SELECT *
FROM table t
INNER JOIN cte2 c ON t.columnID = c.columnIDs
编辑:我不知道你在where子句中会怎么做,我能做的最好是内联函数,然后你可以用它进行内连接:
CREATE FUNCTION dbo.fn_weather (@startDate datetime, @YearRange int, @MonthRange int)
RETURNS table
AS
RETURN
(WITH CTE1(StartDate,EndDate) AS
(
SELECT
DATEADD(MONTH, -1*@MonthRange, @startDate) AS startDate
, DATEADD(MONTH, @MonthRange, @startDate) AS EndDate
UNION ALL
SELECT
DATEADD(YEAR,-1,startDate)
, DATEADD(YEAR,-1,EndDate)
FROM CTE1
WHERE CTE1.StartDate > DATEADD(YEAR, -1*(@YearRange-1), @startDate)
)
SELECT DISTINCT ID
FROM table AS t
INNER JOIN cte1 c ON t.date BETWEEN c.startDate AND c.EndDate)
然后你可以像任何其他表一样进行内连接
INNER JOIN dbo.fn_weather(GETDATE(),10,1) AS fnw ON fnw.ID = table.ID
将过滤掉您需要的行。
答案 1 :(得分:0)
另一种可变驱动的潜在解决方案作为存储过程......
CREATE PROCEDURE GetRecordsFromDateRange
@StartDate as Date,
@EndDate as Date,
@numYearsBack as int
as
BEGIN
Declare @useStartDate Date
Declare @useEndDate Date
Set @useStartDate = DATEADD(month,-1,@StartDate)
Set @useEndDate = DATEADD(month,1,@EndDate)
Select
Data Fields
From table t
Where
MONTH(t.TableDateColumn) >= MONTH(@useStartDate)
AND MONTH(t.TableDateColumn) <= MONTH(@useEndDate)
AND YEAR(t.TableDateColumn) >= YEAR(@useEndDate) - @numYearsBack
END
答案 2 :(得分:0)
这适用于MS SQL Server。欢迎您修改。
create procedure dbo.weather
@myDate datetime,
@monthInterval int=1,
@yearsToSearch int=10
as
declare @startDate datetime=dateadd(month,-@monthInterval,@myDate),
@endDate datetime=dateadd(month,@monthInterval,@myDate),
@cnt int=0
declare @tmp table(<your def here>)
while @cnt<=@yearsToSearch
begin
insert @tmp(<field list here>)
select <field list here> from <your_table_here>
where <dateField> between @startDate and @endDate
select @startDate=DATEADD(year,-1,@startDate),@endDate=DATEADD(year,-1,@endDate),@cnt=@cnt+1
end
select * from @tmp
答案 3 :(得分:0)
这很有效。
首先,我创建了三个变量,一个用于您的日期,一个用于您的日间隔,一个用于您的年度间隔。
然后我创建了2个临时表,一个包含日期和月份,另一个包含可能的年份。
然后将两个临时表内部连接到您选择的表。
DECLARE @Date AS DATETIME = '2016-01-15'
DECLARE @YearInterval AS INT = 10
DECLARE @DayInterval AS INT = 30
;WITH DayMonthCTE AS (
SELECT
DATEADD(d, -@DayInterval, @Date) AS myDate
UNION ALL
SELECT
DATEADD(DAY, 1, myDate) AS myDate
FROM
DayMonthCTE
WHERE
DATEADD(DAY, 1, myDate) <= DATEADD(d, @DayInterval, @Date)
)
SELECT
FORMAT(myDate, 'dd-MM') AS [dayMonth]
INTO
#DateRange
FROM
DayMonthCTE
OPTION
(MAXRECURSION 0)
;WITH YearCTE AS (
SELECT
YEAR(@Date) - @YearInterval AS myYear
UNION ALL
SELECT
myYear + 1
FROM
YearCTE
WHERE
myYear < YEAR(@Date)
)
SELECT
myYear AS [Year]
INTO
#YearRange
FROM
YearCTE
SELECT
*
FROM
YOURTABLE AS D
INNER JOIN #DateRange AS DR ON FORMAT(D.Date, 'dd-MM') = DR.dayMonth
INNER JOIN #YearRange AS YR ON YEAR(D.Date) = YR.Year