2017-05-12 21 views
0

Staのような略語を扱います。サンタ、またはMaに等しい。マリアまたはマと等しい。where句の略語

SELECT * FROM Table1 A WITH(NOLOCK) WHERE A.Name LIKE '%ma%' 

このクエリは、マリアのためですが、問題は、それはまた名前がmarie

ケース1が含まれ含まれています。結果はmariama、およびma.とその逆となり、ユーザーの入力maを。

ケース2:ユーザ入力Maria出力はMa. TeresaまたはMaria TeresaまたはMa Teresaだろうと同じことがstaシナリオになります。

ケース3:ユーザ入力staの場合、結果はsanta,sta.およびstaになり、その逆も同様です。

ケース4:ユーザー入力の通常名(ホセ)の略語なしの結果は、この問題にJose

のように任意のアイデアでしょうか?またはこの問題の最善のアプローチは何ですか?

ありがとうございます。

+2

あなたの質問を編集し、サンプルデータと希望する結果を提供してください。 –

+0

私の質問を編集しました、ありがとうございました。 – Joseph

答えて

0

NormalizedName列に正規化した値を検索するための名前を提供

これは、検索かどうかをチェックする機能でありますmama. ....

CREATE FUNCTION [dbo].[StringContains] 
(
-- Add the parameters for the function here 
@String1 VARCHAR(MAX), 
@String2 VARCHAR(MAX) 
) 
RETURNS BIT 
AS 
BEGIN 
-- Declare the return variable here 
DECLARE @Result BIT = 0 

DECLARE @IsContain INT = 0 

DECLARE @Equivalents TABLE 
(
    ID INT IDENTITY(1,1), 
    Text1 VARCHAR(50), 
    Text2 VARCHAR(50) 
) 
INSERT INTO @Equivalents (Text1, Text2) 
VALUES ('ma. ','maria'), 
('ma. ','ma '), 
('ma ','maria'), 
('sta. ','santa'), 
('sta. ','sta '), 
('sta ','santa') 

DECLARE @ID INT = 1 
DECLARE @TOTAL INT = (SELECT COUNT(1) FROM @Equivalents) 
WHILE @ID <= @TOTAL 
BEGIN 
    DECLARE 
     @Temp1 VARCHAR(MAX) = @String1, 
     @Temp2 VARCHAR(MAX) = @String2, 
     @Text1 VARCHAR(50), 
     @Text2 VARCHAR(50) 
    SELECT TOP 1 
     @Text1 = Text1, 
     @Text2 = Text2 
    FROM @Equivalents 
    WHERE ID = @ID 

    IF @Temp1 LIKE '%'[email protected]+'%' AND @Temp2 LIKE '%'[email protected]+'%' 
    BEGIN 
     SET @String2 = REPLACE(@Temp2,@Text2,@Text1) 
    END 
    ELSE IF @Temp1 LIKE '%'[email protected]+'%' AND @Temp2 LIKE '%'[email protected]+'%' 
    BEGIN 
     SET @String2 = REPLACE(@Temp2,@Text1,@Text2) 
    END 

    IF @String1 LIKE '%'[email protected]+'%' 
    BEGIN 
     SET @IsContain += 1 
    END 

    SET @ID += 1 
END 

SET @Result = (CASE WHEN @IsContain > 0 THEN 1 ELSE 0 END) 
RETURN @Result 
END 

が含まれており、これはクエリです。

DECLARE @Text VARCHAR(MAX) = 'maria' 
SELECT TOP 100 FullName,* FROM dbo.Table1 WITH(NOLOCK) 
WHERE dbo.StringContains(FullName,@Text) = 1 
1

あなたは略語のための期間を持っているので、これはあなたがやりたいことがあります

WHERE ' ' + A.Name + ' ' LIKE '% Ma. %' 
2

一つのアプローチは、すべての略語と彼らがに対応のリストを持つことです。

基本的には、略語をフルネームに展開する別のテーブルを作成します。

AbbrevsAbbrev, Name

ご例えば、それは、これらの行が含まれます:

Abbrev Name 
ma  Maria 
ma  Ma. 
ma. Maria 
ma. Ma 
sta Santa 
sta Sta. 
sta. Santa 
sta. sta 

は、ユーザーが提供した文字列を加えたこの名前のすべての可能な同義語を探します。このような何かを:

DECLARE @ParamInput nvarchar(255); 
SET @ParamInput = 'ma'; 

SELECT * 
FROM YourTable 
WHERE 
    YourTable.Name = @ParamInput 
    OR YourTable.Name IN 
    (
     SELECT Abbrevs.Name 
     FROM Abbrevs 
     WHERE Abbrevs.Abbrev = @ParamInput 
    ) 
; 

あなたは、ユーザが定義してみましょうとAbbrevsテーブルを編集することができます。ユーザー入力とテーブルの両方が省略形を有していてもよく、そしてあなたが検索のためLIKE、ない簡単な=を使用する必要がある場合


は、その後、私は次のような何かをしたいです。

まだ(というか、特定の名前の可能性のある略語のリスト)略語を展開する別のテーブルがあります:

Abbrev Name 
ma  Maria 
ma. Maria 
sta Santa 
sta. Santa 

それに加えて、私は与えられた名前を正規化機能を持っているでしょう。この関数は、指定された名前で可能な略語を検索し、それらを展開します。

たとえば、Ma. Teresaと指定すると、関数はAbbrevsテーブルを使用してMaria Teresaを返します。

メインテーブルには、略称を持つことができる元の名前のフィールドNameがあります。私は別の(計算されたまたは永続化された)列NormalizedNameを追加します。この列はこの関数によって設定されます。実際には、このような列を通常の永続列として作成し、Name列が変更されたときにその値を更新するトリガーを書きました。正規化の1つのステップは、すべての文字列を大文字にすることでした。ドット、カンマ、ダッシュなどの記号をすべて破棄したり、二重スペースを単一スペースに置き換えたりするなど、他のルールを組み込むことができます。Nameの値のみをユーザーに表示します。

ユーザは、私は同じ機能を使用して、指定された名前を正規化するために検索して簡単

WHERE NormalizedName LIKE '%'[email protected]+'%' 
+0

ユーザが 'Maria'を入力すると、出力は' Ma 'になります。 Teresa'または 'Maria Teresa'または' Ma Teresa'? LIKE IN機能はありますか? – Joseph

+0

@ JAlc、私は答えを広げ、私が使用したアイデアを追加しました。 –

+0

ありがとうございました! – Joseph