Sql 使用单词对每个单词进行“like”查询

Sql 使用单词对每个单词进行“like”查询,sql,sql-server,tsql,azure-sql-database,Sql,Sql Server,Tsql,Azure Sql Database,我得到了这个查询,它可以正确地循环一组单词,并对每个单词的特定字段执行类似的条件,如果需要,还可以搜索DOB 有人能在While循环的需要范围内找到这样做的方法吗?我找不到一种使用STRING_SPLIT的方法来实现这一点,我已经尝试过了,但是我无法添加一个类似于使用这个的方法 SET STATISTICS IO ON SET STATISTICS TIME ON --what will become stored proc parameters DECLARE @searchwords NV

我得到了这个查询,它可以正确地循环一组单词,并对每个单词的特定字段执行类似的条件,如果需要,还可以搜索DOB

有人能在While循环的需要范围内找到这样做的方法吗?我找不到一种使用STRING_SPLIT的方法来实现这一点,我已经尝试过了,但是我无法添加一个类似于使用这个的方法

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

尝试使用以下查询

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
  (
    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 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
    )

我的坏@Leran2002,有没有一个简单的方法,如果不传递单词,但低日期和高日期是,它将显示一个结果?@James-我改变了我的答案。作为变体,您可以使用临时表。@James-I又添加了一个变体。这里不使用临时表。我认为第二个变体更好。带领带的选项非常有趣。如果没有它,结果是不正确的,因此它显然是查询结果的关键。你介意解释一下原因吗?看到图片了吗-