如何使用筛选字符串筛选日期范围(SQL Server)

如何使用筛选字符串筛选日期范围(SQL Server),sql,sql-server,date,where-clause,Sql,Sql Server,Date,Where Clause,我正在尝试根据SQL Server中的输入字符串筛选日期范围 -- 'All Years', '30', '60', '90', '2019', '2020', etc. declare @dateRange nvarchar(20) = '90' select [date], [data] from someTable where ( @dateRange = case @dateRange when 30 then date >= getDate() - 30 whe

我正在尝试根据SQL Server中的输入字符串筛选日期范围

-- 'All Years', '30', '60', '90', '2019', '2020', etc.
declare @dateRange nvarchar(20) = '90' 

select 
[date],
[data]
from someTable
where (
  @dateRange = case @dateRange
  when 30 then date >= getDate() - 30
  when 60 then date >= getDate() - 60
  when 90 then date >= getDate() - 90
  when 'All Years' then date
  else datePart('year', date) = @dateRange
  end
)

如何使用where子句的大小写来选择日期范围?

我建议使用布尔逻辑,而不是
大小写表达式。这为您提供了更细粒度的控制——尽管逻辑仍然很麻烦,并且可能通过采用另一种方法来简化

where 
    (
        @dateRage in ('30', '60', '90') 
        and date >= getDate - try_cast(@dateRange as int)
    )
    or @dateRange = 'All Years'
    or (
        @dateRage not in ('30', '60', '90', 'All Years')
        and datePart('year', date) = @dateRange
    )
)
由于一年永远不会与
'30'
'60'
'90'
'All Years'
匹配,最后一个表达式可能可以简化:

where 
    (
        @dateRage in ('30', '60', '90') 
        and date >= getDate - try_cast(@dateRange as int)
    )
    or @dateRange = 'All Years'
    or datePart('year', date) = @dateRange
)

编辑-从评论中:

<100为日范围,>2000为年范围

这使事情变得更简单:

where 
    @dateRange = 'All Years'
    or (
        try_cast(@dateRage as int) < 100 
        and date >= getDate - try_cast(@dateRange as int)
    )
    or (
        try_cast(@dateRage as int) > 2000 
        and datePart('year', date) = @dateRange
    )
在哪里
@日期范围='所有年份'
或(
试试施法(@dateRage为int)<100
and date>=getDate-try_cast(@dateRange为int)
)
或(
试一试_cast(@dateRage as int)>2000
日期部分('year',date)=@dateRange
)

你把问题复杂化了。不要使用单个参数来完成应该是2的工作。使用开始日期和结束日期,如果您想要“一切”,则将这两个日期都传递给
NULL

DECLARE@Startdate日期,
@结束日期;
--设置@StartDate=。。。
--设置@EndDate=。。。
选择[日期],
[数据]
从某处
其中([date]>=@StartDate和[date]<@EndDate)
或(@StartDate为空,@EndDate为空)
选项(重新编译);
重新编译就在这里,因为查询的catch-all部分可能会导致错误的查询计划缓存,所以最好每次都重新生成它

如果出于未知原因,您必须传递字符串(我建议您不要传递,并修复设计),然后使用一些
CASE
表达式来设置开始和结束日期:

DECLARE@Param varchar(15);
声明@Startdate日期,
@结束日期;
当TRY_CONVERT(int,@Param)<1000时选择@StartDate=CASE,然后选择DATEADD(DAY,TRY_CONVERT(int,@Param)*-1,GETDATE())
当TRY_CONVERT(int,@Param)>1000时,则DATEFROMPARTS(TRY_CONVERT(int,@Param),1,1)
完,,
@EndDate=尝试转换(int,@Param)<1000然后添加日期(DAY,1,GETDATE())时的大小写
当TRY_CONVERT(int,@Param)>1000时,则DATEFROMPARTS(TRY_CONVERT(int,@Param)+1,1,1)
结束;

如您所见,逻辑非常奇怪,
TRY\u CONVERT
的内容非常混乱,因此这不是建议的方法。

什么是“日期范围”
'2019'
?你把问题复杂化了。有两个参数,一个开始日期和一个结束日期,使用
=
<100
是日期范围,
<2000
是年份范围2000不是范围,而是数字。这是100美元。范围大约为30-60,或日期为2020-01-01至2020-06-30。它们是隐含范围。。。过去30天,2019年的所有时间,等等。当将nvarchar值“所有年份”转换为数据类型int时,获取
转换失败。
@dateRange nvarchar(20)=“所有年份”
和datePart('year',date)=@dateRange
对SARGability来说并不好,记住。@Matthew:是的,当然。我们需要
试试cast()
。固定的