2013-06-18 83 views
0

我使用MS SQL 2008和我有一个来自这样一个状态字段:如何过滤SQL查询购买完全匹配字符串?

"REF CNF PCNF REL" 

我需要得到所有状态CNF的订单,而无需返回PCNF。 我可以在WHERE STATUS LIKE '% CNF %'之前和之后使用空格,但如果CNF是第一个或最后一个状态,它将起作用。该工作

一个解决办法是:

WHERE 
    PATINDEX('CNF %',STATUS)=0 AND 
    PATINDEX('% CNF %',STATUS)=0 AND 
    PATINDEX('% CNF',STATUS)=0 

但是,这仅仅是可怕的。 谢谢,

+2

你应该将状态字段标准化到它自己的表中,然后这个问题基本消失。当您需要定期处理该字段的“子数据”时,请勿将格式化的数据和/或多个数据存储在单个字段中。 –

回答

2

正如Marc B.所说,你应该规范化你的表,以避免在一个字段中存储多个值。

如果没有凭据要做到这一点,或者如果你想保持你的模型,因为它,你可以试试你的字符串前后添加空格:

WHERE ' '+STATUS+' ' LIKE '% CNF %' 

这样你不必担心CNF是您列表中的第一项或最后一项。

我不知道它是最优雅/有效的解决方案,但它的工作原理。

+0

这不涉及在评估where子句之前对结果集中的每一行执行串联吗?这可能会在一张大桌子上变得昂贵。 –

+0

当然,但不能超过3例'PATINDEX'调用。寻找字符串模式('LIKE')已经非常昂贵。为了有效,标准化+索引是关键。 –

0

为什么不干脆

WHERE STATUS LIKE '% CNF%' OR STATUS LIKE 'CNF%' 

通配符%匹配任何字符,也没有。

+0

如果CNF出现在第一位?结果几乎和OP的解决方案一样长。那么如果有'CNFF'呢? –

+0

第一名?是不是......或状态像'CNF%''? – Mackie

+1

是的,我同意,但'CNFF'仍然出来(我假设这个csae可能在未来发生,如果不是现在,因为OP在他/她寻找的价值前后使用空格作为分隔符)。另外,这并不比OP的解决方案短。 –

0

使用SQL 2008's own internal functions,我能想到的最好的是他得到了下来,只留下两个象条件:

where STATUS like 'CNF%' or STATUS like '%[^P]CNF%' 

但是,如果你愿意install a .Net add-on,你可以使用正则表达式,像这样:

where 1 = dbo.RegExpLike(STATUS, '(CNF| CNF)')