【问题标题】:Exclude Functions from where clause in Sql server从 Sql server 中的 where 子句中排除函数
【发布时间】:2016-07-13 13:31:05
【问题描述】:

我在stored procedures 之一中使用过query

SELECT officeid, rdate
FROM dbo.mytable
Where OfficeID   = OfficeID
  AND YEAR(h.rDate) = @year
  AND MONTH(h.rDate) BETWEEN 1 AND 4

由于在Where clause 中使用了函数MONTHYEAR,上述查询无法成为SARG ( Search Argument)。这会在stored procedure 执行期间导致Index scan。有没有办法重写上面的查询来处理上面的逻辑(不带function

(注:rdatedatetime 日期类型,@yearINT 数据类型)

【问题讨论】:

  • 您可以更改参数吗?如果您可以传入日期参数​​而不是 int,将会简单得多。当然,它仍然可以完成,但传递一个日期要干净得多。
  • 实际上没有在 SSRS 报告中使用此存储过程。 @year 参数来自年份组合

标签: sql sql-server tsql stored-procedures sql-server-2012


【解决方案1】:

使用伪值..

下面这个函数是SARGABLE(但会很长),因为 CAST( DATETIME to DATE) is SARAGABLE,所以会使用索引。

示例:

Cast(h.rDate as DATE) 
between datefromparts(@year,01,01) 
 and datefromparts(@year,04,30)

【讨论】:

    【解决方案2】:

    使用日期范围比较。例如,

     SELECT officeid, rdate
        FROM dbo.mytable
        Where OfficeID   = OfficeID
        --Filter by dates that are between January 1st, midnight, inclusive, and
        --May 1st, exclusive, in the desired year
        AND h.rDate >= Convert(DateTime,'1/1/' + Convert(VarChar(4),@year))
        AND h.rDate < Convert(DateTime,'5/1/' + Convert(VarChar(4),@year))
    

    【讨论】:

    • 如果您将日期字符串切换为符合 ANSI 的 yyyy-mm-dd 以避免任何本地化问题,这会更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多