請求書を保存するテーブルがあり、それから統計を取得しようとしていますが、残念ながらテーブルの作成が不十分であり、nvarcharフィールドにいくつかの重要な情報が混ざっています。料金の免除は、フロントエンドによって解析される非常にdaliesque文字列のこのフィールドに存在します。 3453.234;exempt;Invoice Total...
したがって、いくつかの単語を除外するクエリを作成します。私の問題は、キーワードのリスト(キャンセル、免除)に応じてレコードを除外できるクエリを実行する方法です。そのため、この単語のいずれかがフィールドにある場合、金額は考慮されません。
それを行うクエリを作成することはそれほど難しくありません。最初に、ワイルドカードを使用したLIKEを使用してテーブルを結合するクエリを作成します。次に、このクエリからすべてを除外します。
私の意味を確認するには、次の簡単な例を参照してください。 http://sqlfiddle.com/#!6/619fb/2
あるいは、ここで例を再現しました:
--Create tables for comparing data
CREATE TABLE Invoice
(
InvoiceID INT NOT NULL IDENTITY,
InvoiceData varchar(200) NOT NULL,
);
CREATE TABLE BadWords
(
BadWordID INT NOT NULL IDENTITY,
BadWord varchar(10) NOT NULL
);
--Insert data
INSERT INTO Invoice (InvoiceData)
VALUES ('This is some invoice data'), ('it is about'), ('something interesting that'),
('you should look at'), ('because its got invoice information');
INSERT INTO BadWords (BadWord)
VALUES ('this'),('invoice');
--Test query:
SELECT *
FROM Invoice
WHERE InvoiceID NOT IN (
SELECT InvoiceID
FROM Invoice i
INNER JOIN BadWords b ON i.InvoiceData LIKE '%' + b.BadWord + '%'
)
数十万行ある場合、パフォーマンスに問題がある可能性があります。詳細な情報がないと、パフォーマンスの高いクエリを提供することは困難です(たとえば、NOT CONTAINSフリーテキストクエリを使用すると、パフォーマンスが向上する可能性があります)。
全文検索 は、複雑な文字列をインデックス化するためのより豊かな方法です。ケースに文章が含まれていないことは承知しておりますが、FTSは引き続き機能します。
ワイルドカード検索の代わりに、連結された値を別々の部分に分割できます。これを達成するには多くの方法があります。 this のリンクを読むと、適切なリンクが表示されます。次に、データをセットワイズに処理できます。これは、nvarchar内の位置が一貫しているか、少なくとも明確に定義されていることを前提としています。
次のいずれかの方法で、クエリを実行するたびにテーブルスキャンが発生する可能性があります。a)述語に先行ワイルドカードがある場合、パーサーはインデックスを使用しません。またはb)フィルターする前に値を分割する必要があります。 。
何らかの方法で分割された値を含むビューにインデックスを付けることができれば、適切に機能する可能性があります。
select *
from invoice
where invoicedata not like '%invoice%'
or invoicedata not like '%this%'