如何使用筛选字符串筛选日期范围(SQL Server)
我正在尝试根据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
-- '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()
。固定的