首先,我为这里糟糕的格式道歉。
其次我应该事先说明改变表模式不是一种选择。
所以我的表定义如下:
Pin varchar
OfferCode varchar
Pin将包含以下数据:
ABC,
ABC123
OfferCode将包含以下数据:
123个
123〜124〜125
我需要一个查询来检查Pin / OfferCode组合的计数,当我说OfferCode时,我的意思是由代字号分隔的单个项目。
例如,如果有一行看起来像abc, 123
而另一行看起来像abc,123~124
,并且我搜索Pin=abc,OfferCode=123
我的数量计数得到一个计数= 2。
显然我可以对此进行类似的查询:
SELECT count(1) from MyTable (nolock) where OfferCode like '%' + @OfferCode + '%' and Pin = @Pin
在这里使用like
是非常昂贵的,我希望可能有更有效的方法。
我也在考虑使用拆分字符串解决方案。我有一个表值函数SplitString(string,delim)
将返回表OutParam
,但我不太确定如何将其应用于表列与字符串。 这是否值得追求?看起来它会更昂贵,但我无法找到一个可行的解决方案来与like
解决方案进行比较。
答案 0 :(得分:1)
像这里一样使用是非常昂贵的,我希望可能有更有效的方式
有效的方法是规范化架构并将每个OfferCode
放在自己的行中。
然后您的查询更像(尽管您可能需要根据您的架构使用交集表):
select count(*)
from MyTable
where OfferCode = @OfferCode
and Pin = @Pin
答案 1 :(得分:1)
如果您的优惠代码不是3位数,那么您的喜欢/%解决方案是开放的(如果有优惠代码123和1234,搜索类似'%123%'会返回两者,这是错误的)。您可以这样使用字符串函数:
SELECT Pin, count(1)
FROM MyTable (nolock)
CROSS APPLY SplitString(OfferCode,'~') OutParam
WHERE OutParam.Value = @OfferCode and Pin = @Pin
GROUP BY Pin
如果你有一个相对较小的桌子,你可以逃脱这个。如果您正在处理大量行或遇到性能问题,那么将其规范化为RedFilter建议会更有效。
答案 2 :(得分:1)
以下是使用like
解决此问题的一种方法,这是在搜索分隔字符串时获取完全匹配同时避免'%123%' matches '123' and '1234'
问题的标准:
-- Create some test data
declare @table table (
Pin varchar(10) not null
, OfferCode varchar(100) not null
)
insert into @table select 'abc', '123'
insert into @table select 'abc', '123~124'
-- Mock some proc params
declare @Pin varchar(10) = 'abc'
declare @OfferCode varchar(10) = '123'
-- Run the actual query
select count(*) as Matches
from @table
where Pin = @Pin
-- Append delimiters to find exact matches
and '~' + OfferCode + '~' like '%~' + @OfferCode + '~%'
正如您所看到的,我们将分隔符添加到搜索的字符串中,并将搜索字符串添加到匹配中,从而避免其他答案中提到的错误。
我非常怀疑字符串拆分功能会比like
产生更好的性能,但使用more recently suggested methods中的某些功能可能值得一两次测试。如果仍有不可接受的性能,您可以选择以下几种方法:
<强>更新强>
OfferCode
(或'~' + OfferCode + '~'
的{{3}})上尝试索引。与SQL Server不会使用带有like
和通配符的索引的神话相反,这是computed persisted column。答案 3 :(得分:0)
实际上,LIKE条件的成本远低于进行任何字符串操作和比较。
http://www.simple-talk.com/sql/performance/the-seven-sins-against-tsql-performance/