很简单,以下哪种方法在WHERE
子句中更好地检索FIELD_NAME
NOT NULL 和 NOT Empty
WHERE DATALENGTH(FIELD_NAME) > 0
或
WHERE ISNULL(FIELD_NAME, '') <> ''
我被告知第一种方法会给某些类型的字段带来虚假结果......同意?
答案 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, ...
执行计划:
注意#1:您可以看到Select #2
(WHERE 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