SQL 日期逻辑子句

SQL Date Logic Clause

在理解如何让 Where 子句与此日期结构一起工作时遇到问题。

这是主要逻辑。我只想要从之前的 3 月 1 日开始到昨天结束的数据。

示例#1: 所以今天是 2015 年 2 月 13 日 这意味着我需要 (2014-03-012015-02-12)[=13 之间的数据=]

示例#2: 假设今天是 2015 年 3 月 20 日,这意味着我需要 (2015-03-012015-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)));