これは、パフォーマンスに多くの微妙な影響がある、実際には複雑なトピックです。あなたは本当にErland Sommarskogすることにより、これらの優れた記事を読んでする必要があります。
Dynamic Search Conditions in T-SQL
The Curse and Blessings of Dynamic SQL
何このため、クエリ・アプローチ「1つのフリーサイズない」がありますので、あなたがどのように微妙なパフォーマンスへの影響がありますこの。どんなに遅いものであっても、質問を適切な答えに戻すだけでなく、この記事:Dynamic Search Conditions in T-SQL by Erland Sommarskogをご覧ください。それはあらゆる方法をカバーし、各方法のPROと短所を非常に詳細に示します。
検索列の最小範囲と最大範囲を決定でき、検索列がNOT NULLの場合、(@ Search IS NULL OR Col = @ Search)、see this area of the above linked articleよりも優れた処理を行うことができます。しかし、記事全体を読む必要があります、あなたの状況に依存する非常に多くのバリエーションがあります、あなたは本当に複数のアプローチを習得し、いつそれらを使用する必要があります。
単一の文字列パラメータ内で複数の用語を検索する場合は、その文字列を分割する必要があります。
分割機能を作成する必要があります。
SELECT
*
FROM YourTable y
INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
I prefer the number table approach to split a string in TSQLが、それぞれの長所と短所を説明する前のリンクを参照してください、SQL Serverで文字列を分割するための多数の方法があります。これは、スプリット機能を使用することができる方法です。
番号表法が機能するために
、あなたは1〜10,000行を含むテーブルNumbers
を作成します。この1つのタイムテーブルの設定を、実行する必要があります。
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
番号テーブルが設定されるとこのsplit関数を作成:
CREATE FUNCTION [dbo].[FN_ListToTable]
(
@SplitOn char(1) --REQUIRED, the character to split the @List string on
,@List varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN
(
----------------
--SINGLE QUERY-- --this will not return empty rows
----------------
SELECT
ListValue
FROM (SELECT
LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
FROM (
SELECT @SplitOn + @List + @SplitOn AS List2
) AS dt
INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
WHERE SUBSTRING(List2, number, 1) = @SplitOn
) dt2
WHERE ListValue IS NOT NULL AND ListValue!=''
);
GO
をあなたは簡単にテーブルにCSV文字列を分割し、それに参加することができます:
select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')
OUTPUT:
ListValue
-----------------------
1
2
3
4
5
6777
(6 row(s) affected)
あなたは、このような複数の検索条件文字列を使用することができます。
DECLARE @Persons table (FirstName varchar(50) , LastName varchar(50), EmailAddress varchar(200))
INSERT INTO @Persons VALUES ('aaa','bbb','[email protected]')
INSERT INTO @Persons VALUES ('xxx','yyy','[email protected]')
INSERT INTO @Persons VALUES ('aaa','yyy','[email protected]')
INSERT INTO @Persons VALUES ('111','222','[email protected]')
declare @searchTerm varchar(50)
set @searchTerm = 'aaa bbb'
--this should use an index on FirstName and LastName if they exist, no index usage on EmailAddress
select
p.* --<<"*" isn't good, only list the columns you need
FROM @Persons p
INNER JOIN dbo.FN_ListToTable(' ',@searchTerm) b on p.FirstName=b.Listvalue
UNION
select
p.* --<<"*" isn't good, only list the columns you need
FROM @Persons p
INNER JOIN dbo.FN_ListToTable(' ',@searchTerm) b on p.LastName=b.Listvalue
UNION
select
p.* --<<"*" isn't good, only list the columns you need
FROM @Persons p
INNER JOIN dbo.FN_ListToTable(' ',@searchTerm) b on p.EmailAddress like '%'+b.Listvalue+'%'
OUTPUT:
FirstName LastName EmailAddress
---------- ---------- -------------------------
aaa bbb [email protected]
aaa yyy [email protected]
xxx yyy [email protected]
(3 row(s) affected)
この方法は、任意の数のパラメータのために動作します:
aaa
aaa
aaa bbb
aaa bbb
aaa bbb eee
aaa bbb eee ddd
aaa bbb eee