Sql 使用单词对每个单词进行“like”查询
我得到了这个查询,它可以正确地循环一组单词,并对每个单词的特定字段执行类似的条件,如果需要,还可以搜索DOB 有人能在While循环的需要范围内找到这样做的方法吗?我找不到一种使用STRING_SPLIT的方法来实现这一点,我已经尝试过了,但是我无法添加一个类似于使用这个的方法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
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又添加了一个变体。这里不使用临时表。我认为第二个变体更好。带领带的选项非常有趣。如果没有它,结果是不正确的,因此它显然是查询结果的关键。你介意解释一下原因吗?看到图片了吗-