如何使用筛选字符串筛选日期范围(sql server)

8dtrkrch  于 2021-07-27  发布在  Java
关注(0)|答案(2)|浏览(612)

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

-- '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子句选择日期范围?

blmhpbnm

blmhpbnm1#

我建议使用布尔逻辑而不是 case 表情。这将为您提供更细粒度的控制—尽管逻辑仍然很繁琐,并且可能通过采用另一种方法来简化。

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
    )
8ljdwjyq

8ljdwjyq2#

你把问题复杂化了。不要用一个参数来做应该是2的工作。使用开始和结束日期,然后通过 NULL 如果你想要“一切”:

DECLARE @Startdate date,
        @EndDate date;

--SET @StartDate = ...
--SET @EndDate = ...        

SELECT [date],
       [data]
FROM someTable
WHERE ([date] >= @StartDate AND [date] < @EndDate)
   OR (@StartDate IS NULL AND @EndDate IS NULL)
OPTION (RECOMPILE);

由于查询的catch all部分可能会导致错误的查询计划缓存,因此最好每次都重新生成它。
如果出于某种未知的原因,您必须传递字符串(我真的建议您不要传递,并修复设计),那么使用一些 CASE 用于设置开始和结束日期的表达式:

DECLARE @Param varchar(15);

DECLARE @Startdate date,
        @EndDate date;

SELECT @StartDate = CASE WHEN TRY_CONVERT(int,@Param) < 1000 THEN DATEADD(DAY, TRY_CONVERT(int,@Param) * -1, GETDATE())
                         WHEN TRY_CONVERT(int,@Param) > 1000 THEN DATEFROMPARTS(TRY_CONVERT(int,@Param),1,1)
                    END,
       @EndDate = CASE WHEN TRY_CONVERT(int,@Param) < 1000 THEN DATEADD(DAY,1,GETDATE())
                       WHEN TRY_CONVERT(int,@Param) > 1000 THEN DATEFROMPARTS(TRY_CONVERT(int,@Param)+1,1,1)
                  END;

正如你所看到的,这个逻辑真的很奇怪 TRY_CONVERT 这真的是一个泥泞的东西,所以这不是建议的方法。

相关问题