3

我经常遇到这样的情况,我可以像这样编写 t-sql 查询的条件......

DECLARE @FirstName NVARCHAR(500)    
SET @FirstName ='Joe'

SELECT * 
FROM dbo.Customers c
WHERE 
    CASE 
        WHEN  @FirstName <> ''  THEN
            CASE WHEN c.FirstName= @FirstName THEN 1 ELSE 0 END
        ELSE 1
     END = 1 

或者像这样...

SELECT * 
FROM dbo.Customers c
WHERE 
    (@FirstName = ''  OR (@FirstName <> '' AND c.FirstName = @FirstName))

它们都产生相同的结果,并且两个查询计划似乎相同。

所以我很好奇哪一个是最佳实践,或者一个比另一个有什么陷阱?

4

3 回答 3

3

我认为在这种情况下主要也是关于可读性的,但在第一个查询示例中你做得更多。您正在强制数据库为每行创建一个 0 或 1 的值,并要求数据库检查该值是 0 还是 1。在我看来,创建查询时步骤越少越好。

我会选择第二种方法,尽管您可能可以摆脱 @FirstName<> '' 因为它是不必要的,所以您的查询会清理更多:

SELECT * 
FROM dbo.Customers c
WHERE 
    (@FirstName = ''  OR c.FirstName = @FirstName)

编辑:马丁史密斯提供了一个非常好的见解,您可能需要考虑。

于 2012-07-30T16:14:08.860 回答
0

我更喜欢第二种的变体——将你的变量默认为空,因为在最近的 SQL Server 版本中有一个特定的优化可以针对它进行优化。

DECLARE @FirstName NVARCHAR(500) = NULL

SELECT * 
FROM dbo.Customers c
WHERE 
    (@FirstName IS NULL OR c.FirstName = @FirstName)

有关更多详细信息,请参阅此 SO 答案:https ://stackoverflow.com/a/3415629/1564603

于 2012-07-31T03:46:49.583 回答
0

使用 LIKE 来避免 Null Mathing 怎么样?

声明 @FirstName NVARCHAR(500) = NULL

SELECT * FROM dbo.Customers c WHERE (c.FirstName LIKE @FirstName+'%')

我认为结果可能是相同的,甚至更有趣不管搜索的时间成本更长的事实

于 2016-01-20T18:10:14.513 回答