我继承了一些C#应用程序代码,它具有流畅的SQL查询构建器,可在我们的代码库中使用。一些更常见的查询应用过滤器,如“今天或之后的日期”。这些过滤器作为查询构建器的元数据存储在SQL表中,在调查性能和死锁问题的同时,我意识到这些查询组件不可思议。
此构建器构建的典型查询如下所示:
DECLARE @systemDate DATETIME
SET @systemDate = [dbo].GetSystemDate()
SELECT [table1].* FROM [dbo].[XXX] AS [table1]
WHERE ... AND DateDiff(d, @systemDate, [table1].PaymentDate) <= 0
AND ...
PaymentDate列存储为具有时间组件的日期时间。 GetSystemDate()在午夜返回日期时间 - 即2017-10-18 00:00:00.000
问题在于,即使我在覆盖索引中有PaymentDate,SQL Server也无法对其进行搜索,因为它位于DateDiff()函数中。但是,查询构建器的设计使我很容易用一个更高效,可搜索的表达式替换,该表达式将应用于所有构造的SQL查询。
对于以下内容,如果时间组件也在查询列中发挥作用,并且生成的查询需要将相同的结果返回到现有的DateDiff()调用,那么对于以下内容的等效sargable查询是什么?我已经看到其他解决方案使用DateAdd()和比较,但我担心这些行为不同,因为我们的数据中有时间组件。
OperatorDisplayName OperatorExpression ValueExpression ColumnExpression
Today = 0 DateDiff(d, @systemDate, {0})
This Week = 0 DateDiff(ww, @systemDate, {0})
Last Week = -1 DateDiff(ww, @systemDate, {0})
This Month = 0 DateDiff(m, @systemDate, {0})
Last Month = -1 DateDiff(m, @systemDate, {0})
On or Before Today <= 0 DateDiff(d, @systemDate, {0})
On or After Today >= 0 DateDiff(d, @systemDate, {0})
Before Today < 0 DateDiff(d, @systemDate, {0})
After Today > 0 DateDiff(d, @systemDate, {0})
答案 0 :(得分:0)
由于@systemDate
没有时间组件,您可以构建&gt; =&lt;比较:
OperatorDisplayName OperatorExpression ValueExpression ColumnExpression
Today = 0 {0} >= @systemDate AND {0} < DATEADD(d, 1, @systemDate)
您并没有真正以这种方式使用Operator或Value,因为它内置于列表达式中。
星期和月份运算符会变得更复杂,因为您的表达式需要包含代码来计算基于@systemDate
的星期/月的第一天,但网上已有样本。< / p>