1

まず、ここで書式設定が不十分であることをお詫びします。

2 番目に、テーブル スキーマの変更はオプションではないことを前もって述べておく必要があります。

したがって、次のように定義されたテーブルがあります。

ピンvarchar
オファーコードvarchar

ピンには、
abc、
abc123などのデータが含まれます。

OfferCode には次のようなデータが含まれます:
123
123~124~125

Pin/OfferCode の組み合わせの数を確認するクエリが必要です。OfferCode と言うときは、チルダで区切られた個々のアイテムを意味します。

たとえば、 のように見える 1 つの行と のようabc, 123に見える別の行があり、カウント = 2 を取得するために I wandabc,123~124のカウントを検索するとします。Pin=abc,OfferCode=123

明らかに、これと同様のクエリを実行できます。
SELECT count(1) from MyTable (nolock) where OfferCode like '%' + @OfferCode + '%' and Pin = @Pin

ここでの使用likeは非常に高価であり、より効率的な方法があることを願っています。

また、分割文字列ソリューションの使用も検討しています。SplitString(string,delim)table を返すテーブル値関数がOutParamありますが、これをテーブル列と文字列に適用する方法がよくわかりません。これは追求する価値があるでしょうか?はるかに高価になるようですが、ソリューションと比較するための実用的なソリューションを取得できませんlike

4

4 に答える 4

1

この問題に使用する 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のいくつかを使用して、1、2 回テストする価値があるかもしれません。それでもパフォーマンスが許容できない場合は、いくつかのオプションがあります。

更新しました:

  • OfferCode(または の計算された永続列)でインデックスを試してください'~' + OfferCode + '~'likeSQL Server はワイルドカードを使用したインデックスを使用しないという神話に反して、これは実際に役立つ可能性があります
  • 全文検索をご覧ください。
  • 文字列スプリッターを使用して、このテーブルの正規化されたバージョンを作成します。この表を使用して、カウントを実行します。何らかのスケジュールまたはイベント (トリガーなど) に従って、このテーブルを更新します。
  • 標準的な検索用語がある場合は、これらの数を事前に計算し、定期的に保存します。
于 2012-10-01T19:33:40.573 に答える
1

3 桁以外のオファー コードがある場合、like/% ソリューションはバグに対してオープンです (オファー コードが 123 と 1234 の場合、like '%123%' を検索すると両方が返されますが、これは誤りです)。次のように文字列関数を使用できます。

SELECT Pin, count(1) 
FROM MyTable (nolock) 
CROSS APPLY SplitString(OfferCode,'~') OutParam 
WHERE OutParam.Value = @OfferCode and Pin = @Pin
GROUP BY Pin

比較的小さなテーブルを使用している場合は、おそらくこれでうまくいくでしょう。多数の行を扱っている場合、またはパフォーマンスの問題が発生している場合は、RedFilter が提案するように正規化する方が効果的です。

于 2012-10-01T17:44:25.907 に答える
1

ここでの使用は非常に高価であり、より効率的な方法があることを願っています

効率的な方法は、スキーマを正規化し、それぞれOfferCodeを独自の行に配置することです。

次に、クエリは次のようになります (ただし、スキーマによっては交差テーブルを使用する必要がある場合があります)。

select count(*)
from MyTable 
where OfferCode = @OfferCode 
    and Pin = @Pin
于 2012-10-01T17:23:37.270 に答える
0

実際、LIKE条件は、あらゆる種類の文字列操作や比較を行うよりもはるかに低コストになります。

http://www.simple-talk.com/sql/performance/the-seven-sins-against-tsql-performance/

于 2012-10-01T17:52:09.800 に答える