0

很简单,在子句中检索非空非空WHERE的记录FIELD_NAME时,以下哪种方法更好

WHERE DATALENGTH(FIELD_NAME) > 0

或者

WHERE ISNULL(FIELD_NAME, '') <> ''

更新

我被告知,第一种方法会为某些类型的字段提供虚假结果......同意吗?

4

7 回答 7

4

首先,

select *
from table
where column <> ''

将给出完全相同的结果

select *
from table
where isnull(column, '') <> ''

因为条件是UNKNOWN而不是的记录FALSE仍然会被过滤掉。我通常会选择第一个选项。

DATALENGTH计算尾随空格,与之比较''不计算。是否 ' '比较 unequal取决于您''。如果你这样做,你需要DATALENGTH. 如果你不这样做,只需与 比较''

请注意,对于TEXT/NTEXT类型,不支持比较,但支持DATALENGTH

于 2013-05-09T15:39:06.977 回答
2

ISNULL是最好的方法,而不是DATALENGTH.

于 2013-05-09T15:18:23.300 回答
2

使用 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 SeekIndex Scanp.MiddleName <> ''

注意 #2: DATALENGTH(NULL) 给出 NULL 所以DATALENGTH(FIELD_NAME) > 0条件是错误的。

注意#3:ISNULL()函数用于表示(SELECT 子句)而不是用于编写条件。

于 2013-05-09T15:55:00.660 回答
1

我会用

WHERE ISNULL(FIELD_NAME, '') <> ''

可能出现的一个问题是不会返回带有空格的记录。你在寻找这样的记录吗?

我不确定 DATALENGTH 的意外结果。我会使用 ISNULL 方法,以便 SQL Server 不需要花时间计算被比较记录的长度。我不知道两者之间的性能差异,只是一种直觉。

于 2013-05-09T15:31:14.683 回答
1

我会使用以下之一:

where coalesce(field_name, '') <> ''

或者

where field_name <> '' or field_name is not null

或者

where field_name <> ''

第一个是标准 SQL(coalesce()是标准的,isnull()不是)。最后一个不是最明显的,但 NULL 会导致比较失败,它允许使用索引。

于 2013-05-09T15:35:06.190 回答
1

如果您的“非空”条件包含空格,那么我将使用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
于 2013-05-09T15:39:11.810 回答
0
RTRIM(LTRIM(ISNULL(FIELD_NAME, ''))) <> '' will handle spaces and NULLS
于 2013-05-09T15:39:02.977 回答