DATALENGTH()或ISNULL()用于检索非空且非空的字段

时间:2013-05-09 15:16:08

标签: sql sql-server

很简单,以下哪种方法在WHERE子句中更好地检索FIELD_NAME NOT NULL NOT Empty

WHERE DATALENGTH(FIELD_NAME) > 0

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

更新

我被告知第一种方法会给某些类型的字段带来虚假结果......同意?

7 个答案:

答案 0 :(得分:4)

首先,

select *
from table
where column <> ''

将提供与

完全相同的结果
select *
from table
where isnull(column, '') <> ''

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

DATALENGTH计算尾随空格,与''的比较不会。您是否希望 ' '比较不等于'',由您决定。如果您这样做,则需要DATALENGTH。如果不这样做,只需与''进行比较。

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

答案 1 :(得分:2)

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

答案 2 :(得分: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, ...

执行计划: enter image description here

注意#1:您可以看到Select #2WHERE p.MiddleName <> '')提供了最佳性能,并且是SQL Server使用Index Seek(范围扫描)而不是* [完全] * Index Scan。这是因为p.MiddleName <> ''是SARG(至少在SQL Server 2008 R2中)。

注意#2:DATALENGTH(NULL)给出NULL,因此DATALENGTH(FIELD_NAME) > 0条件错误。

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

答案 3 :(得分:1)

我会用

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

可能出现的一个问题是,不会返回包含空格的记录。你在寻找那样的唱片吗?

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

答案 4 :(得分:1)

我会使用以下其中一项:

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

where field_name <> '' or field_name is not null

where field_name <> ''

第一个是标准SQL(coalesce()是标准的,isnull()不是)。最后一个不是最明显的,但NULL将无法进行比较,它允许使用索引。

答案 5 :(得分: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

答案 6 :(得分:0)

RTRIM(LTRIM(ISNULL(FIELD_NAME, ''))) <> '' will handle spaces and NULLS