很简单,在子句中检索非空且非空WHERE
的记录FIELD_NAME
时,以下哪种方法更好
WHERE DATALENGTH(FIELD_NAME) > 0
或者
WHERE ISNULL(FIELD_NAME, '') <> ''
更新
我被告知,第一种方法会为某些类型的字段提供虚假结果......同意吗?
很简单,在子句中检索非空且非空WHERE
的记录FIELD_NAME
时,以下哪种方法更好
WHERE DATALENGTH(FIELD_NAME) > 0
或者
WHERE ISNULL(FIELD_NAME, '') <> ''
我被告知,第一种方法会为某些类型的字段提供虚假结果......同意吗?
首先,
select *
from table
where column <> ''
将给出完全相同的结果
select *
from table
where isnull(column, '') <> ''
因为条件是UNKNOWN
而不是的记录FALSE
仍然会被过滤掉。我通常会选择第一个选项。
DATALENGTH
计算尾随空格,与之比较''
不计算。是否要 ' '
比较 unequal取决于您''
。如果你这样做,你需要DATALENGTH
. 如果你不这样做,只需与 比较''
。
请注意,对于TEXT
/NTEXT
类型,不支持比较,但支持DATALENGTH
。
ISNULL
是最好的方法,而不是DATALENGTH
.
使用 AdventureWorks2008 R2 数据库的简短测试:
CREATE INDEX IN_Person_MiddleName_FirstName_LastName
ON Person.Person (MiddleName,FirstName,LastName) ;
GO
SET STATISTICS IO ON;
SET NOCOUNT ON;
GO
PRINT 'Select #1: Full Scan';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p;
PRINT 'Select #2: Seek (range scan)';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p
WHERE p.MiddleName <> '' -- p.MiddleName <> '' implies that {p.MiddleName IS NOT NULL} condition to be true
PRINT 'Select #3: Full Scan';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p
WHERE DATALENGTH(p.MiddleName) > 0;
PRINT 'Select #4: Full Scan';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p
WHERE ISNULL(p.MiddleName, '') <> '';
结果:
Select #1: Full Scan
Table 'Person'. Scan count 1, logical reads 105, ...
Select #2: Seek (range scan)
Table 'Person'. Scan count 2, logical reads 67, ... <-- minimum logical reads
Select #3: Full Scan
Table 'Person'. Scan count 1, logical reads 105, ...
Select #4: Full Scan
Table 'Person'. Scan count 1, logical reads 105, ...
执行计划:
注意 #1:您可以看到Select #2
( ) 提供了最佳性能,并且是 SQL Server 使用(范围扫描) 而不是 *[FULL] *WHERE p.MiddleName <> ''
的唯一情况。这是因为是 SARG(至少在 SQL Server 2008 R2 中)。Index Seek
Index Scan
p.MiddleName <> ''
注意 #2: DATALENGTH(NULL) 给出 NULL 所以DATALENGTH(FIELD_NAME) > 0
条件是错误的。
注意#3:ISNULL()函数用于表示(SELECT 子句)而不是用于编写条件。
我会用
WHERE ISNULL(FIELD_NAME, '') <> ''
可能出现的一个问题是不会返回带有空格的记录。你在寻找这样的记录吗?
我不确定 DATALENGTH 的意外结果。我会使用 ISNULL 方法,以便 SQL Server 不需要花时间计算被比较记录的长度。我不知道两者之间的性能差异,只是一种直觉。
我会使用以下之一:
where coalesce(field_name, '') <> ''
或者
where field_name <> '' or field_name is not null
或者
where field_name <> ''
第一个是标准 SQL(coalesce()
是标准的,isnull()
不是)。最后一个不是最明显的,但 NULL 会导致比较失败,它允许使用索引。
如果您的“非空”条件包含空格,那么我将使用nullif
select case when nullif(' ', '') is null then 'y' else 'n' end
y
declare @d varchar(50)
set @d = null
select case when nullif(@d, '') is null then 'y' else 'n' end
y
RTRIM(LTRIM(ISNULL(FIELD_NAME, ''))) <> '' will handle spaces and NULLS