2017-11-16 8 views
1

私は、単語のセットをループしたり、必要に応じてDOBを検索しながら各単語の特定のフィールドで同様の条件を実行したりするのに、各単語の "like"クエリーのための単語の使用

誰もがWhileループの必要性の中でこれを行う方法を見ることができますか?私はSTRING_SPLITを使ってこれを行う方法を見つけられませんでしたが、これを使ってLIKEを追加することはできません。

SET STATISTICS IO ON 
SET STATISTICS TIME ON 

--what will become stored proc parameters 
DECLARE @searchwords NVARCHAR(max) = 'mary jo' --can accept many search words 
DECLARE @LowerDate date = '01 Jan 1980' --could be NULL 
DECLARE @UpperDate date = '31 Dec 1980' --could be NULL 
--local variables 
DECLARE @word NVARCHAR(50) 
Declare @ID int 

Create Table #SearchWords 
(
    ID int IDENTITY(1,1), 
    Word varchar(50) 
) 

Create Table #Results 
(
    ClientID int, 
    FirstName varchar(50), 
    LastName varchar(50), 
    VerificationCode varchar(100), 
    DOB date 
) 

Insert into #SearchWords 
(
    Word 
) 
SELECT 
    value 
FROM 
    STRING_SPLIT(@searchwords, ' ') 
WHERE 
    RTRIM(value) <> '' 

While (Select Count(*) From #SearchWords) > 0 
Begin 

    Select Top 1 
     @ID = ID, 
     @Word = Word 
    From 
     #SearchWords 

    INSERT INTO #Results 
    (
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    ) 
    SELECT 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM 
     Client 
    WHERE 
     (FirstName like '%' + @Word + '%' or 
     LastName like '%' + @Word + '%' or 
     VerificationCode like '%' + @Word + '%') 

    Delete #SearchWords Where ID = @ID 
End 

IF (@LowerDate IS NOT NULL and @UpperDate IS NOT NULL) 
BEGIN 
    INSERT INTO #Results 
    (
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    ) 
    SELECT 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM 
     Client 
    WHERE 
     (DOB >= @LowerDate and DOB <= @UpperDate) 
END 

select * from #Results 

drop table #Results 
drop table #SearchWords 

答えて

1

SELECT TOP 1 WITH TIES 
    ClientID, 
    FirstName, 
    LastName, 
    VerificationCode, 
    DOB 
FROM 
    (
    SELECT 
     1 RowPriority, 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM Client c 
    WHERE EXISTS(
       SELECT * 
       FROM #SearchWords s 
       WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%')) 
       OR (c.LastName LIKE CONCAT('%',s.Word,'%')) 
       OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%')) 
      ) 
     AND DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB) 

    UNION ALL 

    SELECT 
     2 RowPriority, 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM Client c 
    WHERE DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB) 
) q 
ORDER BY RowPriority 

つ以上に一時的なテーブルずに次のクエリ

SELECT 
    ClientID, 
    FirstName, 
    LastName, 
    VerificationCode, 
    DOB 
FROM Client c 
WHERE EXISTS(
      SELECT * 
      FROM #SearchWords s 
      WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%')) 
      OR (c.LastName LIKE CONCAT('%',s.Word,'%')) 
      OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%')) 
     ) 
    AND DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB) 

あなたのコメントからの質問

SELECT 
    ClientID, 
    FirstName, 
    LastName, 
    VerificationCode, 
    DOB 
INTO #Result 
FROM Client c 
WHERE EXISTS(
      SELECT * 
      FROM #SearchWords s 
      WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%')) 
      OR (c.LastName LIKE CONCAT('%',s.Word,'%')) 
      OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%')) 
     ) 
    AND DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB) 

IF(EXISTS(SELECT * FROM #Result)) 
BEGIN 
    SELECT * 
    FROM #Result 
END 
ELSE 
BEGIN 
    SELECT 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM Client 
    WHERE DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB) 
END 

DROP TABLE #Result 

バリアントのバリアントを使用してみてくださいバリアント

SELECT TOP 1 WITH TIES 
    ClientID, 
    FirstName, 
    LastName, 
    VerificationCode, 
    DOB 
FROM 
    (
    -- the first scenario - we use only words filter without the DOB filter 
    SELECT 
     1 RowPriority, -- max priority 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM Client c 
    WHERE EXISTS(
       SELECT * 
       FROM #SearchWords s 
       WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%')) 
       OR (c.LastName LIKE CONCAT('%',s.Word,'%')) 
       OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%')) 
      ) 
     AND @LowerDate IS NULL 

    UNION ALL 

    -- the second scenario - we use words and DOB filters 
    SELECT 
     2 RowPriority, 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM Client c 
    WHERE EXISTS(
       SELECT * 
       FROM #SearchWords s 
       WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%')) 
       OR (c.LastName LIKE CONCAT('%',s.Word,'%')) 
       OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%')) 
      ) 
     AND DOB BETWEEN @LowerDate AND @UpperDate 

    -- the third scenario - we use only DOB filter 
    SELECT 
     3 RowPriority, -- min priority 
     ClientID, 
     FirstName, 
     LastName, 
     VerificationCode, 
     DOB 
    FROM Client c 
    WHERE (SELECT COUNT(*) FROM #SearchWords)=0 
     AND DOB BETWEEN @LowerDate AND @UpperDate 
) q 
ORDER BY RowPriority 

補助変数

-- an auxiliary variable 
DECLARE @Scenario int=CASE 
     WHEN (SELECT COUNT(*) FROM #SearchWords)>0 THEN IIF(@LowerDate IS NULL,1,2) 
     WHEN (SELECT COUNT(*) FROM #SearchWords)=0 AND @LowerDate IS NOT NULL THEN 3 
    END 

SELECT 
    ClientID, 
    FirstName, 
    LastName, 
    VerificationCode, 
    DOB 
FROM Client c 
WHERE 
    (
     (
      @Scenario IN(1,2) 
      AND EXISTS(
        SELECT * 
        FROM #SearchWords s 
        WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%')) 
        OR (c.LastName LIKE CONCAT('%',s.Word,'%')) 
        OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%')) 
       ) 
     ) 
     OR 
     @Scenario=3 -- this scenario doesn't use word filter 
    ) 
    AND 
    (
     (@Scenario IN(2,3) AND DOB BETWEEN @LowerDate AND @UpperDate) 
     OR 
     @Scenario=1 -- this scenario doesn't use DOB filter 
    ) 
+0

を有する変異体は、御馳走を働いた、そのためにありがとうございます。 – Philip

+0

私の悪い@ Leran2002は、単語が渡されてもLowerDateとUpperDateが結果を表示するという簡単な方法はありますか? – Philip

+0

@James - 私は私の答えを変更しました。バリアントとして、一時テーブルを使用することができます。 – Leran2002

関連する問題