SQL 日期逻辑子句
SQL Date Logic Clause
在理解如何让 Where 子句与此日期结构一起工作时遇到问题。
这是主要逻辑。我只想要从之前的 3 月 1 日开始到昨天结束的数据。
示例#1:
所以今天是 2015 年 2 月 13 日 这意味着我需要 (2014-03-01 和 2015-02-12)[=13 之间的数据=]
示例#2:
假设今天是 2015 年 3 月 20 日,这意味着我需要 (2015-03-01 和 2015-03-19)[= 之间的数据13=]
where 逻辑可能有效,但它不喜欢转换“3/1/”+ 年。但我不确定如何表达它。第一个子句很好,它是损坏的 Case 部分。
查询
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] < CONVERT(VARCHAR(10), GETDATE(), 102)
AND [Request Date] = CASE WHEN
CONVERT(VARCHAR(10), GETDATE(), 102) <
CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE()) , 114)
THEN [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE()-365) , 114)
ELSE [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE() , 114)
END
我也试过了
AND [Request Date] = CASE WHEN
CONVERT(VARCHAR(10), GETDATE(), 102) <
'3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()))
THEN [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()-364))
ELSE [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()))
END
在 Oracle 中,我会这样计算下限:
add_months( trunc( add_months( sysdate, -2 ), 'YEAR'), 2 )
换句话说 - 减去两个月,向下舍入到年初,然后加上两个月。
希望您可以将其转换为使用适当的 TSQL 函数。
我更愿意为@from - @to 范围创建日期时间变量,但如果这是用于视图,我想你必须在 where 子句中进行。
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] < cast(GETDATE() as date)
AND [Request Date] >= CASE WHEN
GETDATE() < CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4)))
THEN CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) - 1 as varchar(4)))
ELSE CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4)))
END
试试这个 where
子句。
WHERE [Request Date]
BETWEEN Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE)
AND Getdate() - 1
此处Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE)
将获取三月份的第一天。加上 -1 年以获得起点。
Getdate() - 1
将定义终点
是这样的吗?始终从 3 月 1 日开始,如果现在是 3 月 1 日或更早,则为上一年,否则为今年。
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] >= dateadd(month, 2, DATEADD(year, DATEDIFF(year, 0, dateadd(month, -2, dateadd(day, -1, getdate()))), 0))
and [Request Date] < DATEADD(day, DATEDIFF(day, 0, getdate()), 0)
首先它减去一天,所以 3 月 1 日不是同一年,然后它减去 2 个月以获得上一年的日期,然后将它四舍五入到年份,然后加上 2 个月到 3 月 1 日。
让我们使用一些测试数据:
DECLARE @MyDate DATETIME = '3/13/2015'
要声明一些我们将设置的变量:
DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
在此代码中,我检查我们是在 3 月 1 日之前还是之后,如果是,我们将使用前一年或今年作为起点(财政年度?)
SELECT @StartDate = CASE WHEN DATEPART(MONTH, @MyDate) < 3 THEN
DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, @MyDate) - 1, 0))
ELSE
DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, @MyDate), 0))
END,
@EndDate = DATEADD(DAY, DATEDIFF(DAY, 0, @MyDate), 0)
这是输出:
SELECT @StartDate 为开始,@EndDate 为结束日期
Start EndDate
2015-03-01 00:00:00.000 2015-03-13 00:00:00.000
我会首先创建一个相当通用的用户定义函数来满足我的需要,因此:
create function dbo.start_of_fiscal_year
(
@today date ,
@fiscal_year_start_month int
)
returns date
as
begin
set @today = case coalesce(@today,'')
when '' then current_timestamp
else @today
end
declare @month_start date = dateadd(day,1-datepart(day,@today),@today)
declare @fiscal_month_number int = case sign( datepart(month,@month_start) - @fiscal_year_start_month )
when -1 then 13
else 1
end
+ ( datepart(month,@month_start) - @fiscal_year_start_month )
declare @fiscal_year_start date = dateadd(month,1-@fiscal_month_number,@month_start)
return @fiscal_year_start
end
go
一旦你有了,你就可以说
declare @today date = current_timetamp
declare @fy_start date = start_of_fiscal_year(@today,3)
select *
from dbo.foo t
where t.report_date >= @fy_start
and t.report_date < @today
甚至
select fiscal_year = datepart(year,start_of_fiscal_year(t.report_date,3)) , count(*)
from dbo.foo t
group by datepart(year,start_of_fiscal_year(t.report_date,3))
你的下限应该是这个。当月份小于3(三月)时,只需要抵消年份即可。
dateadd(
yy,
year(current_timestamp) - 1900 + case when month(current_timestamp) < 3 then -1 else 0 end,
'19000301'
)
没有理由乱用字符串,这非常简洁地巩固了逻辑。我还猜测当当前日期是 3 月 1 日时,您想查询上一年的完整日期。所以你需要稍微调整一下测试。
case when (month(dateadd(dd, -1, current_timestamp)) < 3 ...
并且只是为了好玩:
dateadd(mm, (12-month(current_timestamp-1))/10*-12+2, cast(year(current_timestamp) as char(4)));
在理解如何让 Where 子句与此日期结构一起工作时遇到问题。
这是主要逻辑。我只想要从之前的 3 月 1 日开始到昨天结束的数据。
示例#1: 所以今天是 2015 年 2 月 13 日 这意味着我需要 (2014-03-01 和 2015-02-12)[=13 之间的数据=]
示例#2: 假设今天是 2015 年 3 月 20 日,这意味着我需要 (2015-03-01 和 2015-03-19)[= 之间的数据13=]
where 逻辑可能有效,但它不喜欢转换“3/1/”+ 年。但我不确定如何表达它。第一个子句很好,它是损坏的 Case 部分。
查询
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] < CONVERT(VARCHAR(10), GETDATE(), 102)
AND [Request Date] = CASE WHEN
CONVERT(VARCHAR(10), GETDATE(), 102) <
CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE()) , 114)
THEN [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE()-365) , 114)
ELSE [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE() , 114)
END
我也试过了
AND [Request Date] = CASE WHEN
CONVERT(VARCHAR(10), GETDATE(), 102) <
'3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()))
THEN [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()-364))
ELSE [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()))
END
在 Oracle 中,我会这样计算下限:
add_months( trunc( add_months( sysdate, -2 ), 'YEAR'), 2 )
换句话说 - 减去两个月,向下舍入到年初,然后加上两个月。
希望您可以将其转换为使用适当的 TSQL 函数。
我更愿意为@from - @to 范围创建日期时间变量,但如果这是用于视图,我想你必须在 where 子句中进行。
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] < cast(GETDATE() as date)
AND [Request Date] >= CASE WHEN
GETDATE() < CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4)))
THEN CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) - 1 as varchar(4)))
ELSE CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4)))
END
试试这个 where
子句。
WHERE [Request Date]
BETWEEN Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE)
AND Getdate() - 1
此处Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE)
将获取三月份的第一天。加上 -1 年以获得起点。
Getdate() - 1
将定义终点
是这样的吗?始终从 3 月 1 日开始,如果现在是 3 月 1 日或更早,则为上一年,否则为今年。
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] >= dateadd(month, 2, DATEADD(year, DATEDIFF(year, 0, dateadd(month, -2, dateadd(day, -1, getdate()))), 0))
and [Request Date] < DATEADD(day, DATEDIFF(day, 0, getdate()), 0)
首先它减去一天,所以 3 月 1 日不是同一年,然后它减去 2 个月以获得上一年的日期,然后将它四舍五入到年份,然后加上 2 个月到 3 月 1 日。
让我们使用一些测试数据:
DECLARE @MyDate DATETIME = '3/13/2015'
要声明一些我们将设置的变量:
DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
在此代码中,我检查我们是在 3 月 1 日之前还是之后,如果是,我们将使用前一年或今年作为起点(财政年度?)
SELECT @StartDate = CASE WHEN DATEPART(MONTH, @MyDate) < 3 THEN
DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, @MyDate) - 1, 0))
ELSE
DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, @MyDate), 0))
END,
@EndDate = DATEADD(DAY, DATEDIFF(DAY, 0, @MyDate), 0)
这是输出:
SELECT @StartDate 为开始,@EndDate 为结束日期
Start EndDate
2015-03-01 00:00:00.000 2015-03-13 00:00:00.000
我会首先创建一个相当通用的用户定义函数来满足我的需要,因此:
create function dbo.start_of_fiscal_year
(
@today date ,
@fiscal_year_start_month int
)
returns date
as
begin
set @today = case coalesce(@today,'')
when '' then current_timestamp
else @today
end
declare @month_start date = dateadd(day,1-datepart(day,@today),@today)
declare @fiscal_month_number int = case sign( datepart(month,@month_start) - @fiscal_year_start_month )
when -1 then 13
else 1
end
+ ( datepart(month,@month_start) - @fiscal_year_start_month )
declare @fiscal_year_start date = dateadd(month,1-@fiscal_month_number,@month_start)
return @fiscal_year_start
end
go
一旦你有了,你就可以说
declare @today date = current_timetamp
declare @fy_start date = start_of_fiscal_year(@today,3)
select *
from dbo.foo t
where t.report_date >= @fy_start
and t.report_date < @today
甚至
select fiscal_year = datepart(year,start_of_fiscal_year(t.report_date,3)) , count(*)
from dbo.foo t
group by datepart(year,start_of_fiscal_year(t.report_date,3))
你的下限应该是这个。当月份小于3(三月)时,只需要抵消年份即可。
dateadd(
yy,
year(current_timestamp) - 1900 + case when month(current_timestamp) < 3 then -1 else 0 end,
'19000301'
)
没有理由乱用字符串,这非常简洁地巩固了逻辑。我还猜测当当前日期是 3 月 1 日时,您想查询上一年的完整日期。所以你需要稍微调整一下测试。
case when (month(dateadd(dd, -1, current_timestamp)) < 3 ...
并且只是为了好玩:
dateadd(mm, (12-month(current_timestamp-1))/10*-12+2, cast(year(current_timestamp) as char(4)));