2012-03-26 16 views
2

のは、私のようなテーブルがあるとしましょう:のは、私は、検索ボックスなどのGoogleを持っているとしましょう、今検索の実装

Persons 
    FirstName varchar(50) 
    LastName varchar(50) 
    EmailAddress varchar(200) 

を。言い換えれば、検索ボタン付きのテキストボックスは1つだけです。

通常我々がような何か:私がやりたいのは何

declare @searchTerm varchar(50) 
set @searchTerm = 'tom' 

select * 
    from Persons 
    where (FirstName = @searchTerm) 
    or (LastName = @searchTerm) 
    or (EmailAddress = @searchTerm) 

は@searchTerm変数に(たとえば)の両方の最初と最後の名前を渡すことができるようですが、私の脳はただのdoesnそのクエリをビルドしたくありません。 ;)例えば

​​

アイデアは「トムOR「スミス」は、これらのフィールドに表示されるすべてのレコードを返すことです。

答えて

5

これは、パフォーマンスに多くの微妙な影響がある、実際には複雑なトピックです。あなたは本当に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 
0

あなたは次のようなものを試すことができます:

DECLARE 
    @searchTerm VARCHAR(100), 
    @FirstName VARCHAR(100), 
    @LastName VARCHAR(100) 
SET 
    @searchTerm = 'tom smith' 

SELECT 
    @FirstName = '%' + SUBSTRING(@searchTerm, 1, CHARINDEX(' ', @searchTerm) - 1) + '%', 
    @LastName = '%' + SUBSTRING(@searchTerm, CHARINDEX(' ', @searchTerm) + 1, LEN(@searchTerm)) + '%' 

SELECT * 
FROM 
    Persons 
WHERE 
    FirstName LIKE @FirstName 
OR LastName LIKE @FirstName 
OR EmailAddress LIKE @FirstName 
OR FirstName LIKE @LastName 
OR LastName LIKE @LastName 
OR EmailAddress LIKE @LastName 
関連する問題